ZQuest Classic Coverage Report


Directory: src/
File: src/zc/maps.cpp
Date: 2025-08-13 08:01:38
Exec Total Coverage
Lines: 4060 5059 80.3%
Functions: 289 327 88.4%
Branches: 3115 5091 61.2%

Line Branch Exec Source
1 #include "base/combo.h"
2 #include "base/handles.h"
3 #include "base/util.h"
4 #include "base/zdefs.h"
5 #include "base/general.h"
6 #include <cstring>
7 #include <assert.h>
8 #include <math.h>
9 #include <vector>
10 #include <deque>
11 #include <string>
12 #include <set>
13 #include <array>
14 #include <sstream>
15 using std::set;
16
17 #include "base/qrs.h"
18 #include "base/dmap.h"
19 #include "base/mapscr.h"
20 #include "base/misctypes.h"
21 #include "base/initdata.h"
22 #include "zc/maps.h"
23 #include "zc/zelda.h"
24 #include "zc/zc_ffc.h"
25 #include "tiles.h"
26 #include "sprite.h"
27 #include "gui/jwin.h"
28 #include "base/zsys.h"
29 #include "subscr.h"
30 #include "zc/zc_subscr.h"
31 #include "zc/hero.h"
32 #include "zc/guys.h"
33 #include "zc/ffscript.h"
34 #include "drawing.h"
35 #include "zc/combos.h"
36 #include "zc/replay.h"
37 #include "slopes.h"
38 #include "particles.h"
39 #include <fmt/format.h>
40 #include "zc/render.h"
41 #include "iter.h"
42 #include <ranges>
43
44 // All the temporary screens (and their layers) for the currently loaded map.
45 static mapscr* temporary_screens[136*7];
46 // Set by load_region.
47 static bool screen_in_current_region[136];
48 412 static rpos_handle_t current_region_rpos_handles[136*7];
49 static bool current_region_rpos_handles_dirty;
50 static int current_region_screen_count;
51 static std::pair<const rpos_handle_t*, int> current_region_rpos_handles_scr[136];
52
53 viewport_t viewport;
54 static int viewport_sprite_uid;
55 ViewportMode viewport_mode;
56 int world_w, world_h;
57 int region_scr_dx, region_scr_dy;
58 int region_scr_count;
59 rpos_t region_max_rpos;
60 int region_num_rpos;
61 region_t cur_region, scrolling_region;
62
63 412 maze_state_t maze_state;
64 int scrolling_maze_last_solved_screen;
65
66 575 void maps_init_game_vars()
67 {
68 575 viewport = {};
69 575 viewport_mode = ViewportMode::CenterAndBound;
70 575 viewport_sprite_uid = 1;
71 575 currscr_for_passive_subscr = -1;
72 575 }
73
74 static region_ids_t current_region_ids;
75
76 14616166 static bool is_a_region(int map, int scr)
77 {
78 14616166 return get_region_id(map, scr) != 0;
79 }
80
81 2232 static bool is_same_region_id(int region_origin_scr, int map, int scr)
82 {
83
2/2
✓ Branch 0 taken 772 times.
✓ Branch 1 taken 1460 times.
2232 if (!is_a_region(map, scr)) return false;
84 1460 int region_id = get_region_id(map, region_origin_scr);
85
1/2
✓ Branch 0 taken 1460 times.
✗ Branch 1 not taken.
1460 return region_id && region_id == get_region_id(map, scr);
86 2232 }
87
88 137749126 bool is_in_current_region(int map, int screen)
89 {
90
5/6
✓ Branch 0 taken 137747553 times.
✓ Branch 1 taken 1573 times.
✓ Branch 2 taken 137747553 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12213 times.
✓ Branch 5 taken 137735340 times.
137749126 return map == cur_map && screen >= 0 && screen < 128 && screen_in_current_region[screen];
91 }
92
93 69622303 bool is_in_current_region(int screen)
94 {
95
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 69622302 times.
69622303 return screen < 128 && screen_in_current_region[screen];
96 }
97
98 28995045 bool is_in_current_region(mapscr* scr)
99 {
100
4/4
✓ Branch 0 taken 28980024 times.
✓ Branch 1 taken 15021 times.
✓ Branch 2 taken 462663 times.
✓ Branch 3 taken 28517361 times.
28995045 return scr->map == cur_map && scr->screen < 128 && screen_in_current_region[scr->screen];
101 }
102
103 bool is_in_scrolling_region(int screen)
104 {
105 if (!screenscrolling) return false;
106
107 int x = screen % 16;
108 int y = screen / 16;
109 return
110 scrolling_region.origin_screen_x >= x && scrolling_region.origin_screen_x < x + scrolling_region.screen_width &&
111 scrolling_region.origin_screen_y >= y && scrolling_region.origin_screen_y < y + scrolling_region.screen_height;
112 }
113
114 9016036602 bool is_in_scrolling_region()
115 {
116 9016036602 return cur_region.screen_count > 1;
117 }
118
119 76829448 bool is_extended_height_mode()
120 {
121
2/2
✓ Branch 0 taken 76579314 times.
✓ Branch 1 taken 250134 times.
76829448 return cur_region.screen_height > 1 && (DMaps[cur_dmap].flags & dmfEXTENDEDVIEWPORT);
122 }
123
124 // Returns 0 if this is not a region.
125 15658208 int get_region_id(int map, int screen)
126 {
127
2/2
✓ Branch 0 taken 401435 times.
✓ Branch 1 taken 15256773 times.
15658208 if (screen >= 128) return 0;
128
2/2
✓ Branch 0 taken 15255673 times.
✓ Branch 1 taken 1100 times.
15256773 if (map == cur_region.map) return current_region_ids[screen];
129
130 1100 return Regions[map].get_region_id(screen);
131 15658208 }
132
133 982758 int get_current_region_id()
134 {
135 982758 return get_region_id(cur_map, cur_screen);
136 }
137
138 64215 void calculate_region(int map, int screen, region_t& region, int& region_scr_dx, int& region_scr_dy)
139 {
140 64215 region.map = map;
141
142
3/4
✓ Branch 0 taken 274 times.
✓ Branch 1 taken 63941 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 274 times.
64215 if (!(is_a_region(map, screen)) || screen >= 0x80)
143 {
144 63941 region.region_id = 0;
145 63941 region.origin_screen = screen;
146 63941 region.origin_screen_x = screen % 16;
147 63941 region.origin_screen_y = screen / 16;
148 63941 region.screen_width = 1;
149 63941 region.screen_height = 1;
150 63941 region.screen_count = 1;
151 63941 region.width = 256;
152 63941 region.height = 176;
153 63941 region_scr_dx = 0;
154 63941 region_scr_dy = 0;
155 63941 return;
156 }
157
158 274 int input_scr_x = screen % 16;
159 274 int input_scr_y = screen / 16;
160
161 // For the given screen, find the top-left corner of its region.
162 274 int origin_scr_x = input_scr_x;
163 274 int origin_scr_y = input_scr_y;
164 274 int origin_scr = screen;
165
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 372 times.
434 while (origin_scr_x > 0)
166 {
167
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 160 times.
372 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x - 1, origin_scr_y))) break;
168 160 origin_scr_x--;
169 }
170
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 414 times.
508 while (origin_scr_y > 0)
171 {
172
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 234 times.
414 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, origin_scr_y - 1))) break;
173 234 origin_scr_y--;
174 }
175 274 origin_scr = map_scr_xy_to_index(origin_scr_x, origin_scr_y);
176
177 // Now find the bottom-right corner.
178 274 int region_scr_right = origin_scr_x;
179
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 614 times.
642 while (region_scr_right < 15)
180 {
181
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 368 times.
614 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(region_scr_right + 1, origin_scr_y))) break;
182 368 region_scr_right++;
183 }
184 274 int region_scr_bottom = origin_scr_y;
185
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 832 times.
856 while (region_scr_bottom < 7)
186 {
187
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 582 times.
832 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, region_scr_bottom + 1))) break;
188 582 region_scr_bottom++;
189 }
190
191 274 region.region_id = get_region_id(map, origin_scr);
192 274 region.origin_screen = origin_scr;
193 274 region.origin_screen_x = origin_scr_x;
194 274 region.origin_screen_y = origin_scr_y;
195 274 region.screen_width = region_scr_right - origin_scr_x + 1;
196 274 region.screen_height = region_scr_bottom - origin_scr_y + 1;
197 274 region.screen_count = region.screen_width * region.screen_height;
198 274 region.width = 256 * region.screen_width;
199 274 region.height = 176 * region.screen_height;
200 274 region_scr_dx = input_scr_x - origin_scr_x;
201 274 region_scr_dy = input_scr_y - origin_scr_y;
202
203 DCHECK_RANGE_INCLUSIVE(region.screen_width, 0, 16);
204 DCHECK_RANGE_INCLUSIVE(region.screen_height, 0, 8);
205 64215 }
206
207 35854 void load_region(int dmap, int screen)
208 {
209 35854 clear_temporary_screens();
210
211 35854 int map = DMaps[dmap].map;
212 35854 current_region_ids = Regions[map].get_all_region_ids();
213
214 35854 calculate_region(map, screen, cur_region, region_scr_dx, region_scr_dy);
215 35854 cur_screen = cur_region.origin_screen;
216 35854 world_w = cur_region.width;
217 35854 world_h = cur_region.height;
218 35854 region_scr_count = cur_region.screen_count;
219 35854 region_max_rpos = (rpos_t)(cur_region.screen_count*176 - 1);
220 35854 region_num_rpos = cur_region.screen_count*176;
221 35854 scrolling_maze_last_solved_screen = 0;
222
223 35854 memset(screen_in_current_region, false, sizeof(screen_in_current_region));
224
2/2
✓ Branch 0 taken 36088 times.
✓ Branch 1 taken 35854 times.
71942 for (int x = 0; x < cur_region.screen_width; x++)
225 {
226
2/2
✓ Branch 0 taken 37098 times.
✓ Branch 1 taken 36088 times.
73186 for (int y = 0; y < cur_region.screen_height; y++)
227 {
228 37098 int screen = cur_screen + x + y*16;
229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37098 times.
37098 if (screen < 136)
230 {
231 37098 screen_in_current_region[screen] = true;
232 37098 }
233 37098 }
234 36088 }
235
236 35854 mark_current_region_handles_dirty();
237 35854 }
238
239 35854 static void prepare_current_region_handles()
240 {
241 35854 current_region_rpos_handles_dirty = false;
242 35854 current_region_screen_count = 0;
243
2/2
✓ Branch 0 taken 36202 times.
✓ Branch 1 taken 35854 times.
72056 for (int y = 0; y < cur_region.screen_height; y++)
244 {
245
2/2
✓ Branch 0 taken 37098 times.
✓ Branch 1 taken 36202 times.
73300 for (int x = 0; x < cur_region.screen_width; x++)
246 {
247 37098 int screen = cur_screen + x + y*16;
248 37098 int index_start = current_region_screen_count;
249
2/2
✓ Branch 0 taken 37098 times.
✓ Branch 1 taken 259686 times.
296784 for (int layer = 0; layer <= 6; layer++)
250 {
251 259686 mapscr* scr = get_scr_layer(screen, layer);
252
2/2
✓ Branch 0 taken 84550 times.
✓ Branch 1 taken 175136 times.
259686 if (!scr->is_valid())
253 {
254
1/2
✓ Branch 0 taken 175136 times.
✗ Branch 1 not taken.
175136 if (layer == 0) break;
255 175136 continue;
256 }
257
258 84550 rpos_t base_rpos = POS_TO_RPOS(0, get_region_relative_dx(screen), get_region_relative_dy(screen));
259 84550 current_region_rpos_handles[current_region_screen_count] = {scr, screen, layer, base_rpos, 0};
260 84550 current_region_screen_count += 1;
261 84550 }
262
263 37098 int num_handles_for_scr = current_region_screen_count - index_start;
264 37098 current_region_rpos_handles_scr[screen] = {&current_region_rpos_handles[index_start], num_handles_for_scr};
265 37098 }
266 36202 }
267 35854 }
268
269 1782359281 std::tuple<const rpos_handle_t*, int> get_current_region_handles()
270 {
271 DCHECK(!current_region_rpos_handles_dirty);
272 1782359281 return {current_region_rpos_handles, current_region_screen_count};
273 }
274
275 11056526 std::tuple<const rpos_handle_t*, int> get_current_region_handles(mapscr* scr)
276 {
277 DCHECK(!current_region_rpos_handles_dirty);
278
2/4
✓ Branch 0 taken 11056526 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11056526 times.
11056526 if (scr == special_warp_return_scr || current_region_rpos_handles_dirty)
279 return {nullptr, 0};
280
281
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11056526 times.
11056526 if (cur_screen >= 0x80)
282 {
283 DCHECK(scr == origin_scr);
284 return {nullptr, 0};
285 }
286
287 DCHECK(is_in_current_region(scr));
288 11056526 return current_region_rpos_handles_scr[scr->screen];
289 11056526 }
290
291 35854 void mark_current_region_handles_dirty()
292 {
293 35854 current_region_rpos_handles_dirty = true;
294 35854 }
295
296 36991 void clear_temporary_screens()
297 {
298
2/2
✓ Branch 0 taken 35215432 times.
✓ Branch 1 taken 36991 times.
35252423 for (int i = 0; i < 136*7; i++)
299 {
300
2/2
✓ Branch 0 taken 35160797 times.
✓ Branch 1 taken 54635 times.
35215432 if (temporary_screens[i])
301 {
302 54635 free(temporary_screens[i]);
303 54635 temporary_screens[i] = NULL;
304 54635 }
305 35215432 }
306
307 36991 origin_scr = nullptr;
308 36991 hero_scr = nullptr;
309 36991 }
310
311 27954 std::vector<mapscr*> take_temporary_scrs()
312 {
313
1/2
✓ Branch 0 taken 27954 times.
✗ Branch 1 not taken.
27954 std::vector<mapscr*> screens(temporary_screens, temporary_screens + 136*7);
314
2/2
✓ Branch 0 taken 27954 times.
✓ Branch 1 taken 26612208 times.
26640162 for (int i = 0; i < 136*7; i++)
315 26612208 temporary_screens[i] = nullptr;
316
317 27954 return screens;
318
1/2
✓ Branch 0 taken 27954 times.
✗ Branch 1 not taken.
27954 }
319
320 14550079 void calculate_viewport(viewport_t& viewport, int dmap, int screen, int world_w, int world_h, int x, int y)
321 {
322 // TODO: In future, maybe add x/y centering offsets to zscript (Viewport->TargetXOffset/Viewport->TargetYOffset).
323
324
2/2
✓ Branch 0 taken 14503497 times.
✓ Branch 1 taken 46582 times.
14550079 bool extended_height_mode = (DMaps[dmap].flags & dmfEXTENDEDVIEWPORT) && world_h > 176;
325 14550079 viewport.w = 256;
326 14550079 viewport.h = 176 + (extended_height_mode ? 56 : 0);
327
328
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 14549719 times.
14550079 if (viewport_mode == ViewportMode::Script)
329 360 return;
330
331
2/2
✓ Branch 0 taken 46162 times.
✓ Branch 1 taken 14503557 times.
14549719 if (!is_a_region(DMaps[dmap].map, screen))
332 {
333 14503557 viewport.x = 0;
334 14503557 viewport.y = 0;
335 14503557 }
336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46162 times.
46162 else if (viewport_mode == ViewportMode::CenterAndBound)
337 {
338 // Clamp the viewport to the edges of the region.
339
6/6
✓ Branch 0 taken 8568 times.
✓ Branch 1 taken 37594 times.
✓ Branch 2 taken 6788 times.
✓ Branch 3 taken 39374 times.
✓ Branch 4 taken 8568 times.
✓ Branch 5 taken 30806 times.
46162 viewport.x = CLAMP(0, world_w - viewport.w, x - viewport.w/2);
340
6/6
✓ Branch 0 taken 11856 times.
✓ Branch 1 taken 34306 times.
✓ Branch 2 taken 5650 times.
✓ Branch 3 taken 40512 times.
✓ Branch 4 taken 11856 times.
✓ Branch 5 taken 28656 times.
46162 viewport.y = CLAMP(0, world_h - viewport.h, y - viewport.h/2);
341 46162 }
342 else if (viewport_mode == ViewportMode::Center)
343 {
344 viewport.x = x - viewport.w/2;
345 viewport.y = y - viewport.h/2;
346 }
347 14550079 }
348
349 14549568 sprite* get_viewport_sprite()
350 {
351 14549568 sprite* spr = sprite::getByUID(viewport_sprite_uid);
352
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 14549562 times.
14549568 if (!spr)
353 {
354 6 viewport_sprite_uid = 1; // Hero uid.
355 6 spr = &Hero;
356 6 }
357
358 14549568 return spr;
359 }
360
361 6 void set_viewport_sprite(sprite* spr)
362 {
363 6 viewport_sprite_uid = spr->uid;
364 6 }
365
366 14521614 void update_viewport()
367 {
368 14521614 sprite* spr = get_viewport_sprite();
369 14521614 int x = spr->x + spr->txsz*16/2;
370 14521614 int y = spr->y + spr->tysz*16/2;
371 14521614 calculate_viewport(viewport, cur_dmap, cur_screen, world_w, world_h, x, y);
372 14521614 }
373
374 14309416 void update_heroscr()
375 {
376 void playLevelMusic();
377
378 14309416 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
379 14309416 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
380 14309416 int dx = x / 256;
381 14309416 int dy = y / 176;
382 14309416 int new_screen = cur_screen + dx + dy * 16;
383
2/2
✓ Branch 0 taken 14301654 times.
✓ Branch 1 taken 7762 times.
14309416 if (maze_state.active == 1)
384 7762 new_screen = maze_state.scr->screen;
385
7/12
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 14309200 times.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 216 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 216 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 216 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 216 times.
14309416 if (hero_screen != new_screen && dx >= 0 && dy >= 0 && dx < 16 && dy < 8 && is_in_current_region(new_screen))
386 {
387 216 region_scr_dx = dx;
388 216 region_scr_dy = dy;
389 216 hero_screen = new_screen;
390 216 prev_hero_scr = hero_scr;
391 216 hero_scr = get_scr(hero_screen);
392 216 Hero.screen_spawned = hero_screen;
393 216 playLevelMusic();
394 216 }
395
1/2
✓ Branch 0 taken 14309416 times.
✗ Branch 1 not taken.
14309416 if (game->get_regionmapping() == REGION_MAPPING_PHYSICAL)
396 mark_visited(new_screen); // Mark each screen the hero steps foot in as visited
397 14309416 }
398
399 4722 mapscr* determine_hero_screen_from_coords()
400 {
401 4722 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
402 4722 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
403 4722 int dx = x / 256;
404 4722 int dy = y / 176;
405 4722 return get_scr(cur_screen + dx + dy * 16);
406 }
407
408 26924 bool edge_of_region(direction dir)
409 {
410
2/2
✓ Branch 0 taken 26844 times.
✓ Branch 1 taken 80 times.
26924 if (!is_in_scrolling_region()) return true;
411
412 80 int screen_x = hero_screen % 16;
413 80 int screen_y = hero_screen / 16;
414
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 2 times.
80 if (dir == up) screen_y -= 1;
415
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 10 times.
80 if (dir == down) screen_y += 1;
416
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 30 times.
80 if (dir == left) screen_x -= 1;
417
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 38 times.
80 if (dir == right) screen_x += 1;
418
4/8
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 80 times.
✗ Branch 7 not taken.
80 if (screen_x < 0 || screen_x > 16 || screen_y < 0 || screen_y > 8) return true;
419 80 return !is_in_current_region(map_scr_xy_to_index(screen_x, screen_y));
420 26924 }
421
422 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
423 // Coordinates are clamped to the world bounds.
424 212153779 int get_screen_for_world_xy(int x, int y)
425 {
426
2/2
✓ Branch 0 taken 189364167 times.
✓ Branch 1 taken 22789612 times.
212153779 if (!is_in_scrolling_region())
427 189364167 return cur_screen;
428
429 22789612 int dx = std::clamp(x, 0, world_w - 1) / 256;
430 22789612 int dy = std::clamp(y, 0, world_h - 1) / 176;
431 22789612 int origin_screen_x = cur_screen % 16;
432 22789612 int origin_screen_y = cur_screen / 16;
433 22789612 int scr_x = origin_screen_x + dx;
434 22789612 int scr_y = origin_screen_y + dy;
435 22789612 return map_scr_xy_to_index(scr_x, scr_y);
436 212153779 }
437
438 32518504 int get_screen_for_rpos(rpos_t rpos)
439 {
440 32518504 int origin_screen_x = cur_screen % 16;
441 32518504 int origin_screen_y = cur_screen / 16;
442 32518504 int screen = static_cast<int32_t>(rpos) / 176;
443 32518504 int scr_x = origin_screen_x + screen%cur_region.screen_width;
444 32518504 int scr_y = origin_screen_y + screen/cur_region.screen_width;
445 32518504 return map_scr_xy_to_index(scr_x, scr_y);
446 }
447
448 774411837 rpos_handle_t get_rpos_handle(rpos_t rpos, int layer)
449 {
450 DCHECK_LAYER_ZERO_INDEX(layer);
451
2/2
✓ Branch 0 taken 742031293 times.
✓ Branch 1 taken 32380544 times.
774411837 if (!is_in_scrolling_region())
452 742031293 return {get_scr_layer(cur_screen, layer), cur_screen, layer, rpos, RPOS_TO_POS(rpos)};
453 32380544 int screen = get_screen_for_rpos(rpos);
454 32380544 mapscr* scr = get_scr_layer(screen, layer);
455 32380544 return {scr, screen, layer, rpos, RPOS_TO_POS(rpos)};
456 774411837 }
457
458 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
459 // Coordinates are clamped to the world bounds.
460 3492398730 rpos_handle_t get_rpos_handle_for_world_xy(int x, int y, int layer)
461 {
462 3492398730 x = std::clamp(x, 0, world_w - 1);
463 3492398730 y = std::clamp(y, 0, world_h - 1);
464
465 DCHECK_LAYER_ZERO_INDEX(layer);
466
2/2
✓ Branch 0 taken 3464661558 times.
✓ Branch 1 taken 27737172 times.
3492398730 if (!is_in_scrolling_region())
467 {
468 3464661558 int pos = COMBOPOS(x, y);
469 3464661558 return {get_scr_layer(cur_screen, layer), cur_screen, layer, (rpos_t)pos, pos};
470 }
471 27737172 return get_rpos_handle(COMBOPOS_REGION(x, y), layer);
472 3492398730 }
473
474 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
475 1926 rpos_handle_t get_rpos_handle_for_screen(int screen, int layer, int pos)
476 {
477 DCHECK_LAYER_ZERO_INDEX(layer);
478 1926 return {get_scr_layer(screen, layer), screen, layer, POS_TO_RPOS(pos, screen), pos};
479 }
480
481 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
482 // Use this instead of the other `get_pos_handle_for_screen` if you already have a reference to the screen.
483 62247 rpos_handle_t get_rpos_handle_for_scr(mapscr* scr, int layer, int pos)
484 {
485 DCHECK_LAYER_ZERO_INDEX(layer);
486 62247 return {scr, scr->screen, layer, POS_TO_RPOS(pos, scr->screen), pos};
487 }
488
489 25183265 void change_rpos_handle_layer(rpos_handle_t& rpos_handle, int layer)
490 {
491 DCHECK_LAYER_ZERO_INDEX(layer);
492 25183265 rpos_handle.layer = layer;
493 25183265 rpos_handle.scr = get_scr_layer(rpos_handle.screen, layer);
494 25183265 }
495
496 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
497 // Coordinates are clamped to the world bounds.
498 52808 combined_handle_t get_combined_handle_for_world_xy(int x, int y, int layer)
499 {
500 DCHECK_LAYER_ZERO_INDEX(layer);
501
502 52808 x = std::clamp(x, 0, world_w - 1);
503 52808 y = std::clamp(y, 0, world_h - 1);
504
505 52808 auto maybe_ffc_handle = getFFCAt(x, y);
506
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52808 times.
52808 if (maybe_ffc_handle)
507 return maybe_ffc_handle.value();
508
509 52808 auto rpos = COMBOPOS_REGION_B(x, y);
510
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52808 times.
52808 if (rpos == rpos_t::None)
511 return rpos_handle_t();
512 52808 return get_rpos_handle(rpos, layer);
513 52808 }
514
515 // These functions all return _temporary_ screens. Any modifications made to them (either by the engine
516 // directly or via zscript) only last until the next area is loaded (via loadscr).
517
518 // Returns the screen containing the (x, y) world position.
519 1633890687 mapscr* get_scr_for_world_xy(int x, int y)
520 {
521 // Quick path, but should work the same without.
522
2/2
✓ Branch 0 taken 1622757687 times.
✓ Branch 1 taken 11133000 times.
1633890687 if (!is_in_scrolling_region()) return origin_scr;
523 11133000 return get_scr(get_screen_for_world_xy(x, y));
524 1633890687 }
525
526 24512760 mapscr* get_scr_for_rpos(rpos_t rpos)
527 {
528 // Quick path, but should work the same without.
529
2/2
✓ Branch 0 taken 24374814 times.
✓ Branch 1 taken 137946 times.
24512760 if (!is_in_scrolling_region()) return origin_scr;
530 137946 return get_scr(get_screen_for_rpos(rpos));
531 24512760 }
532
533 14 mapscr* get_scr_for_rpos_layer(rpos_t rpos, int layer)
534 {
535 14 return get_scr_layer(get_screen_for_rpos(rpos), layer);
536 }
537
538 // Note: layer=0 is the base screen, 1 is the first layer, etc.
539 2308652236 mapscr* get_scr_for_world_xy_layer(int x, int y, int layer)
540 {
541 DCHECK_LAYER_ZERO_INDEX(layer);
542
2/2
✓ Branch 0 taken 2297232238 times.
✓ Branch 1 taken 11419998 times.
2308652236 if (!is_in_scrolling_region()) return get_scr_layer(cur_screen, layer);
543
2/2
✓ Branch 0 taken 708934 times.
✓ Branch 1 taken 10711064 times.
11419998 return layer == 0 ?
544 708934 get_scr_for_world_xy(x, y) :
545 10711064 get_scr_layer(get_screen_for_world_xy(x, y), layer);
546 2308652236 }
547
548 1833562811 int get_region_screen_offset(int screen)
549 {
550 1833562811 return get_region_relative_dx(screen) + get_region_relative_dy(screen) * cur_region.screen_width;
551 }
552
553 654676679 int get_screen_for_region_index_offset(int offset)
554 {
555 654676679 int scr_dx = offset % cur_region.screen_width;
556 654676679 int scr_dy = offset / cur_region.screen_width;
557 654676679 int screen = cur_screen + scr_dx + scr_dy*16;
558 654676679 return screen;
559 }
560
561 654492842 mapscr* get_scr_for_region_index_offset(int offset)
562 {
563 654492842 int screen = get_screen_for_region_index_offset(offset);
564 654492842 return get_scr(screen);
565 }
566
567 // The screen at (map, screen) must exist.
568 1421742422 mapscr* get_scr(int map, int screen)
569 {
570 1421742422 mapscr* scr = get_scr_maybe(map, screen);
571
1/2
✓ Branch 0 taken 1421742422 times.
✗ Branch 1 not taken.
1421742422 CHECK(scr);
572 1421742422 return scr;
573 }
574
575 837456721 mapscr* get_scr(int screen)
576 {
577 837456721 return get_scr(cur_map, screen);
578 }
579
580 // Returns null if active screen does not exist.
581 1451287465 mapscr* get_scr_maybe(int map, int screen)
582 {
583 DCHECK_RANGE_INCLUSIVE(screen, 0, 135);
584
585
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1451287465 times.
1451287465 if (map == cur_map)
586 {
587
2/2
✓ Branch 0 taken 1430512529 times.
✓ Branch 1 taken 20774936 times.
1451287465 if (screen == cur_screen)
588 1430512529 return origin_scr;
589
590 20774936 int index = screen*7;
591
2/2
✓ Branch 0 taken 20763846 times.
✓ Branch 1 taken 11090 times.
20774936 if (temporary_screens[index])
592 20763846 return temporary_screens[index];
593
594
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11090 times.
11090 if (screen == home_screen)
595 return special_warp_return_scr;
596 11090 }
597
598
3/6
✓ Branch 0 taken 11090 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11090 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11090 times.
11090 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
599 {
600 11090 int index = screen*7;
601
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11090 times.
11090 if (FFCore.ScrollingScreensAll[index])
602 11090 return FFCore.ScrollingScreensAll[index];
603 }
604
605 return nullptr;
606 1451287465 }
607
608 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
609 7053675246 mapscr* get_scr_layer(int map, int screen, int layer)
610 {
611 DCHECK_LAYER_ZERO_INDEX(layer);
612
2/2
✓ Branch 0 taken 6471882271 times.
✓ Branch 1 taken 581792975 times.
7053675246 if (layer == 0)
613 581792975 return get_scr(map, screen);
614
615
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6471882271 times.
6471882271 if (map == cur_map)
616 {
617 6471882271 int index = screen*7 + layer;
618
2/2
✓ Branch 0 taken 6471813871 times.
✓ Branch 1 taken 68400 times.
6471882271 if (temporary_screens[index])
619 6471813871 return temporary_screens[index];
620
621
2/2
✓ Branch 0 taken 1860 times.
✓ Branch 1 taken 66540 times.
68400 if (screen == home_screen)
622 1860 return &special_warp_return_scrs[layer];
623 66540 }
624
625
1/2
✓ Branch 0 taken 66540 times.
✗ Branch 1 not taken.
66540 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
626 {
627 66540 int index = screen*7 + layer;
628
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66540 times.
66540 if (FFCore.ScrollingScreensAll[index])
629 66540 return FFCore.ScrollingScreensAll[index];
630 }
631
632 NOTREACHED();
633 7053675246 }
634
635 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
636 6654529130 mapscr* get_scr_layer(int screen, int layer)
637 {
638 6654529130 return get_scr_layer(cur_map, screen, layer);
639 }
640
641 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
642 // Return nullptr if screen is not valid.
643 397072313 mapscr* get_scr_layer_valid(int screen, int layer)
644 {
645
2/2
✓ Branch 0 taken 78265267 times.
✓ Branch 1 taken 318807046 times.
397072313 if (mapscr* scr = get_scr_layer(cur_map, screen, layer); scr->is_valid())
646 78265267 return scr;
647 318807046 return nullptr;
648 397072313 }
649
650 401 mapscr* get_scr_current_region_dir(int screen, direction dir)
651 {
652 401 int x = get_region_relative_dx(screen);
653 401 int y = get_region_relative_dy(screen);
654
3/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 330 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
401 if (dir == left && x == 0)
655 71 return nullptr;
656
3/4
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
330 if (dir == right && x == 15)
657 return nullptr;
658
3/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
330 if (dir == down && y == 7)
659 return nullptr;
660
3/4
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 141 times.
✓ Branch 2 taken 189 times.
✗ Branch 3 not taken.
330 if (dir == up && y == 0)
661 189 return nullptr;
662
663 141 screen = screen_index_direction(screen, dir);
664
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (is_in_current_region(screen))
665 return get_scr(screen);
666
667 141 return nullptr;
668 401 }
669
670 183837 ffc_handle_t get_ffc_handle(ffc_id_t id)
671 {
672 183837 uint8_t screen = get_screen_for_region_index_offset(id / MAXFFCS);
673 183837 uint8_t i = id % MAXFFCS;
674 183837 mapscr* scr = get_scr(screen);
675 183837 ffcdata* ffc = &scr->getFFC(id % MAXFFCS);
676 183837 return {scr, screen, id, i, ffc};
677 }
678
679 34566 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen, int x, int y)
680 {
681 34566 x += get_region_relative_dx(screen) * 256;
682 34566 y += get_region_relative_dy(screen) * 176;
683 34566 return {x, y};
684 }
685
686 1049500 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen)
687 {
688 1049500 int x = get_region_relative_dx(screen) * 256;
689 1049500 int y = get_region_relative_dy(screen) * 176;
690 1049500 return {x, y};
691 }
692
693 12130462748 int32_t COMBOPOS(int32_t x, int32_t y)
694 {
695 DCHECK(x >= 0 && x < 256 && y >= 0 && y < 176);
696 12130462748 return (y & 0xF0) + (x >> 4);
697 }
698 int32_t COMBOPOS_B(int32_t x, int32_t y)
699 {
700 if(unsigned(x) >= 256 || unsigned(y) >= 176)
701 return -1;
702 return (y & 0xF0) + (x >> 4);
703 }
704 3334371711 int32_t COMBOX(int32_t pos)
705 {
706 3334371711 return pos % 16 * 16;
707 }
708 3334371711 int32_t COMBOY(int32_t pos)
709 {
710 3334371711 return pos & 0xF0;
711 }
712
713 112622847 rpos_t COMBOPOS_REGION(int32_t x, int32_t y)
714 {
715
2/2
✓ Branch 0 taken 84070201 times.
✓ Branch 1 taken 28552646 times.
112622847 if (!is_in_scrolling_region())
716 84070201 return (rpos_t) COMBOPOS(x, y);
717
718 DCHECK(is_in_world_bounds(x, y));
719 28552646 int scr_dx = x / (16*16);
720 28552646 int scr_dy = y / (11*16);
721 28552646 int pos = COMBOPOS(x%256, y%176);
722 28552646 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
723 112622847 }
724 6305089824 rpos_t COMBOPOS_REGION_B(int32_t x, int32_t y)
725 {
726
2/2
✓ Branch 0 taken 1401168 times.
✓ Branch 1 taken 6303688656 times.
6305089824 if (!is_in_world_bounds(x, y))
727 1401168 return rpos_t::None;
728
729 6303688656 int scr_dx = x / (16*16);
730 6303688656 int scr_dy = y / (11*16);
731 6303688656 int pos = COMBOPOS(x%256, y%176);
732 6303688656 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
733 6305089824 }
734 25287068 std::pair<int32_t, int32_t> COMBOXY_REGION(rpos_t rpos)
735 {
736 25287068 int scr_index = static_cast<int32_t>(rpos) / 176;
737 25287068 int scr_dx = scr_index % cur_region.screen_width;
738 25287068 int scr_dy = scr_index / cur_region.screen_width;
739 25287068 int pos = RPOS_TO_POS(rpos);
740 25287068 int x = scr_dx*16*16 + COMBOX(pos);
741 25287068 int y = scr_dy*11*16 + COMBOY(pos);
742 25287068 return {x, y};
743 }
744 60396 int32_t COMBOX_REGION(rpos_t rpos)
745 {
746 60396 auto [x, y] = COMBOXY_REGION(rpos);
747 60396 return x;
748 }
749 12225 int32_t COMBOY_REGION(rpos_t rpos)
750 {
751 12225 auto [x, y] = COMBOXY_REGION(rpos);
752 12225 return y;
753 }
754
755 70177 rpos_t COMBOPOS_REGION_INDEX(int32_t x, int32_t y)
756 {
757 DCHECK(is_in_world_bounds(x, y));
758
1/2
✓ Branch 0 taken 70177 times.
✗ Branch 1 not taken.
70177 if (!is_in_scrolling_region())
759 70177 return (rpos_t)(x + y * 16);
760
761 int scr_dx = x / 16;
762 int scr_dy = y / 11;
763 x %= 16;
764 y %= 11;
765 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + x + y * 16);
766 70177 }
767 70632 std::pair<int32_t, int32_t> COMBOXY_REGION_INDEX(rpos_t rpos)
768 {
769 70632 int scr_index = static_cast<int32_t>(rpos) / 176;
770 70632 int scr_dx = scr_index % cur_region.screen_width;
771 70632 int scr_dy = scr_index / cur_region.screen_width;
772 70632 int pos = RPOS_TO_POS(rpos);
773 70632 int x = scr_dx*16 + pos%16;
774 70632 int y = scr_dy*11 + pos/16;
775 70632 return {x, y};
776 }
777
778 88504176 int32_t mapind(int32_t map, int32_t scr)
779 {
780 88504176 return map * MAPSCRSNORMAL + scr;
781 }
782
783 FONT *get_zc_font(int index);
784
785 extern sprite_list guys, items, Ewpns, Lwpns, chainlinks, decorations;
786 extern movingblock mblock2; //mblock[4]?
787 extern portal mirror_portal;
788
789 void Z_message_d(const char *format,...)
790 {
791 #ifdef _DEBUG
792 char buf[512];
793 va_list ap;
794 va_start(ap, format);
795 vsprintf(buf, format, ap);
796 va_end(ap);
797
798 al_trace("%s",buf);
799 #else
800 format=format;
801 #endif
802 }
803
804
805
806 bool checktrigger=false;
807
808 void debugging_box(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
809 {
810 //reference/optimization: the start of the unused drawing command index can now be queried. -Gleeok
811 int32_t index = script_drawing_commands.GetNext();
812
813 if(index < 0)
814 return;
815
816 int32_t *sdci = &script_drawing_commands[index][0];
817
818 sdci[0] = RECTR;
819 sdci[1] = 30000;
820 sdci[2] = x1*10000;
821 sdci[3] = y1*10000;
822 sdci[4] = x2*10000;
823 sdci[5] = y2*10000;
824 sdci[6] = 10000;
825 sdci[7] = 10000;
826 sdci[8] = 0;
827 sdci[9] = 0;
828 sdci[10] = 0;
829 sdci[11] = 10000;
830 sdci[12] = 1280000;
831 }
832
833 void clear_dmap(word i)
834 {
835 DMaps[i].clear();
836 }
837
838 void clear_dmaps()
839 {
840 for(int32_t i=0; i<MAXDMAPS; i++)
841 {
842 clear_dmap(i);
843 }
844 }
845
846 223615827 int32_t isdungeon(int32_t dmap, int32_t screen)
847 {
848
2/2
✓ Branch 0 taken 223570147 times.
✓ Branch 1 taken 45680 times.
223615827 if (dmap < 0) dmap = cur_dmap;
849
850 // dungeons can have any dlevel above 0
851
2/2
✓ Branch 0 taken 122366382 times.
✓ Branch 1 taken 101249445 times.
223615827 if((DMaps[dmap].type&dmfTYPE) == dmDNGN)
852 {
853
2/2
✓ Branch 0 taken 9961 times.
✓ Branch 1 taken 101239484 times.
101249445 if (get_canonical_scr(cur_map, screen)->flags6&fCAVEROOM)
854 9961 return 0;
855
856 101239484 return 1;
857 }
858
859 // dlevels that aren't dungeons are caves
860
2/2
✓ Branch 0 taken 36827 times.
✓ Branch 1 taken 122329555 times.
122366382 if (get_canonical_scr(cur_map, screen)->flags6&fDUNGEONROOM)
861 36827 return 1;
862
863 122329555 return 0;
864 223615827 }
865
866 39942476 int32_t isdungeon(int32_t screen)
867 {
868 39942476 return isdungeon(cur_dmap, screen);
869 }
870
871 183546414 int32_t isdungeon()
872 {
873 183546414 return isdungeon(cur_dmap, hero_screen);
874 }
875
876 88932 bool canPermSecret(int32_t dmap, int32_t screen)
877 {
878
2/2
✓ Branch 0 taken 13910 times.
✓ Branch 1 taken 75022 times.
88932 return (!isdungeon(dmap, screen) || get_qr(qr_DUNGEON_DMAPS_PERM_SECRETS));
879 }
880
881 1375748203 int32_t MAPCOMBO(int32_t x, int32_t y)
882 {
883 1375748203 x = vbound(x, 0, world_w-1);
884 1375748203 y = vbound(y, 0, world_h-1);
885 1375748203 int pos = COMBOPOS(x%256, y%176);
886 1375748203 mapscr* scr = get_scr_for_world_xy(x, y);
887 1375748203 return scr->data[pos];
888 }
889
890 //specific layers 1 to 6
891 1709728262 int32_t MAPCOMBOL(int32_t layer,int32_t x,int32_t y)
892 {
893 DCHECK(layer >= 1 && layer <= 6);
894
3/4
✓ Branch 0 taken 1689370280 times.
✓ Branch 1 taken 20357982 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1689370280 times.
1709728262 if (!is_in_world_bounds(x, y) || layer <= 0)
895 20357982 return 0;
896
897 1689370280 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
898
2/2
✓ Branch 0 taken 496888043 times.
✓ Branch 1 taken 1192482237 times.
1689370280 if (!m->is_valid())
899 1192482237 return 0;
900
901 496888043 int pos = COMBOPOS(x%256, y%176);
902 496888043 return m->data[pos];
903 1709728262 }
904
905 int32_t MAPCSETL(int32_t layer,int32_t x,int32_t y)
906 {
907 DCHECK(layer >= 1 && layer <= 6);
908 if (!is_in_world_bounds(x, y) || layer <= 0)
909 return 0;
910
911 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
912 if (!m->is_valid())
913 return 0;
914
915 int pos = COMBOPOS(x%256, y%176);
916 return m->cset[pos];
917 }
918
919 189308 int32_t MAPFLAGL(int32_t layer,int32_t x,int32_t y)
920 {
921 DCHECK(layer >= 1 && layer <= 6);
922
2/4
✓ Branch 0 taken 189308 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 189308 times.
189308 if (!is_in_world_bounds(x, y) || layer <= 0)
923 return 0;
924
925 189308 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
926
2/2
✓ Branch 0 taken 148914 times.
✓ Branch 1 taken 40394 times.
189308 if (!m->is_valid())
927 40394 return 0;
928
929 148914 int pos = COMBOPOS(x%256, y%176);
930 148914 return m->sflag[pos];
931 189308 }
932
933 6281 int32_t COMBOTYPEL(int32_t layer,int32_t x,int32_t y)
934 {
935 DCHECK(layer >= 1 && layer <= 6);
936
2/4
✓ Branch 0 taken 6281 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6281 times.
6281 if (!is_in_world_bounds(x, y) || layer <= 0)
937 return 0;
938
939 6281 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
940
2/2
✓ Branch 0 taken 5809 times.
✓ Branch 1 taken 472 times.
6281 if (!m->is_valid())
941 472 return 0;
942
943 5809 int pos = COMBOPOS(x%256, y%176);
944 5809 return combobuf[m->data[pos]].type;
945 6281 }
946
947 189308 int32_t MAPCOMBOFLAGL(int32_t layer,int32_t x,int32_t y)
948 {
949 DCHECK(layer >= 1 && layer <= 6);
950
2/4
✓ Branch 0 taken 189308 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 189308 times.
189308 if (!is_in_world_bounds(x, y) || layer <= 0)
951 return 0;
952
953 189308 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
954
2/2
✓ Branch 0 taken 148914 times.
✓ Branch 1 taken 40394 times.
189308 if (!m->is_valid())
955 40394 return 0;
956
957 148914 int pos = COMBOPOS(x%256, y%176);
958 148914 return combobuf[m->data[pos]].flag;
959 189308 }
960
961
962 // True if the FFC covers x, y and is not ethereal or a changer.
963 2467525204 bool ffcIsAt(const ffc_handle_t& ffc_handle, int32_t x, int32_t y)
964 {
965
2/2
✓ Branch 0 taken 746716438 times.
✓ Branch 1 taken 1720808766 times.
2467525204 if (ffc_handle.data()<=0)
966 746716438 return false;
967
968
2/2
✓ Branch 0 taken 300884500 times.
✓ Branch 1 taken 1419924266 times.
1720808766 if((ffc_handle.ffc->flags&(ffc_changer|ffc_ethereal))!=0)
969 300884500 return false;
970
971 1419924266 int32_t fx=ffc_handle.ffc->x.getInt();
972
4/4
✓ Branch 0 taken 976336635 times.
✓ Branch 1 taken 443587631 times.
✓ Branch 2 taken 866205573 times.
✓ Branch 3 taken 110131062 times.
1419924266 if(x<fx || x>fx+(ffc_handle.scr->ffEffectWidth(ffc_handle.i)-1)) // FFC sizes are weird.
973 1309793204 return false;
974
975 110131062 int32_t fy=ffc_handle.ffc->y.getInt();
976
4/4
✓ Branch 0 taken 80147053 times.
✓ Branch 1 taken 29984009 times.
✓ Branch 2 taken 60079253 times.
✓ Branch 3 taken 20067800 times.
110131062 if(y<fy || y>fy+(ffc_handle.scr->ffEffectHeight(ffc_handle.i)-1))
977 90063262 return false;
978
979 20067800 return true;
980 2467525204 }
981
982 999075493 int32_t MAPFFCOMBO(int32_t x,int32_t y)
983 {
984
2/2
✓ Branch 0 taken 13163663 times.
✓ Branch 1 taken 985911830 times.
999075493 if (auto ffc_handle = getFFCAt(x, y))
985 13163663 return ffc_handle->data();
986 985911830 return 0;
987 999075493 }
988
989 207232 int32_t MAPCSET(int32_t x, int32_t y)
990 {
991
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 207232 times.
207232 if (!is_in_world_bounds(x, y))
992 return 0;
993 207232 mapscr* scr = get_scr_for_world_xy(x, y);
994 207232 int pos = COMBOPOS(x%256, y%176);
995 207232 return scr->cset[pos];
996 207232 }
997
998 73664988 int32_t MAPFLAG(int32_t x, int32_t y)
999 {
1000
2/2
✓ Branch 0 taken 28140 times.
✓ Branch 1 taken 73636848 times.
73664988 if (!is_in_world_bounds(x, y))
1001 28140 return 0;
1002 73636848 mapscr* scr = get_scr_for_world_xy(x, y);
1003 73636848 int pos = COMBOPOS(x%256, y%176);
1004 73636848 return scr->sflag[pos];
1005 73664988 }
1006
1007 163184591 int32_t COMBOTYPE(int32_t x,int32_t y)
1008 {
1009 163184591 int32_t b=1;
1010
2/2
✓ Branch 0 taken 95232965 times.
✓ Branch 1 taken 67951626 times.
163184591 if(x&8) b<<=2;
1011
2/2
✓ Branch 0 taken 81540582 times.
✓ Branch 1 taken 81644009 times.
163184591 if(y&8) b<<=1;
1012
1013
2/2
✓ Branch 0 taken 326362144 times.
✓ Branch 1 taken 163177292 times.
489539436 for (int32_t i = 0; i <= 1; ++i)
1014 {
1015
2/2
✓ Branch 0 taken 316029196 times.
✓ Branch 1 taken 10332948 times.
326362144 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1016 {
1017
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 316029196 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
316029196 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x, y, i)) return cNONE;
1018 316029196 }
1019 else
1020 {
1021
4/4
✓ Branch 0 taken 10451 times.
✓ Branch 1 taken 10322497 times.
✓ Branch 2 taken 3152 times.
✓ Branch 3 taken 7299 times.
10332948 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x, y, i)) return cNONE;
1022 }
1023 326354845 }
1024
1025 163177292 newcombo const& cmb = combobuf[MAPCOMBO(x,y)];
1026
5/6
✓ Branch 0 taken 3590234 times.
✓ Branch 1 taken 159587058 times.
✓ Branch 2 taken 3030548 times.
✓ Branch 3 taken 559686 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3030548 times.
163177292 if (cmb.type == cWATER && (cmb.walk&b) && ((cmb.walk>>4)&b))
1027 {
1028
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3030548 times.
3030548 if(cmb.usrflags&cflag4) return cSHALLOWWATER;
1029
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3030548 times.
3030548 if(cmb.usrflags&cflag3) return cNONE;
1030 3030548 }
1031 163177292 return cmb.type;
1032 163184591 }
1033
1034 50225603 int32_t FFCOMBOTYPE(int32_t x,int32_t y)
1035 {
1036 50225603 return combobuf[MAPFFCOMBO(x,y)].type;
1037 }
1038
1039 4954844 int32_t FFORCOMBO(int32_t x, int32_t y)
1040 {
1041
2/2
✓ Branch 0 taken 58516 times.
✓ Branch 1 taken 4896328 times.
4954844 if (auto ffc_handle = getFFCAt(x, y))
1042 58516 return ffc_handle->data();
1043
1044 4896328 return MAPCOMBO(x,y);
1045 4954844 }
1046
1047 int32_t FFORCOMBOTYPE(int32_t x, int32_t y)
1048 {
1049 for (int32_t i = 0; i <= 1; ++i)
1050 {
1051 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1052 {
1053 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1054 }
1055 else
1056 {
1057 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1058 }
1059 }
1060 int32_t b=1;
1061
1062 if(x&8) b<<=2;
1063
1064 if(y&8) b<<=1;
1065 newcombo const& cmb = combobuf[FFORCOMBO(x,y)];
1066 if (cmb.type == cWATER && (cmb.usrflags&cflag4) && (cmb.walk&b)) return cSHALLOWWATER;
1067 if (cmb.type == cWATER && (cmb.usrflags&cflag3) && (cmb.walk&b)) return cNONE;
1068 return cmb.type;
1069 }
1070
1071 int32_t FFORCOMBO_L(int32_t layer, int32_t x, int32_t y)
1072 {
1073 if (auto ffc_handle = getFFCAt(x, y))
1074 return ffc_handle->data();
1075
1076 return layer ? MAPCOMBOL(layer, x, y) : MAPCOMBO(x,y);
1077 }
1078
1079 int32_t FFORCOMBOTYPE_L(int32_t layer, int32_t x, int32_t y)
1080 {
1081 return combobuf[FFORCOMBO_L(layer,x,y)].type;
1082 }
1083
1084 70154870 int32_t MAPCOMBOFLAG(int32_t x,int32_t y)
1085 {
1086
2/2
✓ Branch 0 taken 27852 times.
✓ Branch 1 taken 70127018 times.
70154870 if (!is_in_world_bounds(x, y))
1087 27852 return 0;
1088
1089 70127018 mapscr* scr = get_scr_for_world_xy(x, y);
1090 70127018 int pos = COMBOPOS(x%256, y%176);
1091 70127018 return combobuf[scr->data[pos]].flag;
1092 70154870 }
1093
1094 56841587 int32_t MAPFFCOMBOFLAG(int32_t x,int32_t y)
1095 {
1096
2/2
✓ Branch 0 taken 746177 times.
✓ Branch 1 taken 56095410 times.
56841587 if (auto ffc_handle = getFFCAt(x, y))
1097 746177 return ffc_handle->cflag();
1098
1099 56095410 return 0;
1100 56841587 }
1101
1102 1313056294 std::optional<ffc_handle_t> getFFCAt(int32_t x, int32_t y)
1103 {
1104 2788859658 return find_ffc([&](const ffc_handle_t& ffc_handle) {
1105 1475803364 return ffcIsAt(ffc_handle, x, y);
1106 });
1107 }
1108
1109 3044 int32_t MAPCOMBO(const rpos_handle_t& rpos_handle)
1110 {
1111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3044 times.
3044 if (!rpos_handle.scr->is_valid()) return 0;
1112 3044 return rpos_handle.data();
1113 3044 }
1114
1115 3161497057 int32_t MAPCOMBO2(int32_t layer, int32_t x, int32_t y)
1116 {
1117 DCHECK_LAYER_NEG1_INDEX(layer);
1118
2/2
✓ Branch 0 taken 22362112 times.
✓ Branch 1 taken 3139134945 times.
3161497057 if (!is_in_world_bounds(x, y)) return 0;
1119
2/2
✓ Branch 0 taken 3067537150 times.
✓ Branch 1 taken 71597795 times.
3139134945 if (layer == -1) return MAPCOMBO(x, y);
1120
1121 3067537150 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1122
2/2
✓ Branch 0 taken 2112128249 times.
✓ Branch 1 taken 955408901 times.
3067537150 if (!rpos_handle.scr->is_valid()) return 0;
1123
1124 955408901 return rpos_handle.data();
1125 3161497057 }
1126
1127 17372399 static void _handle_screen_load_trigger(const combined_handle_t& handle)
1128 {
1129 17372399 auto cid = handle.data();
1130 17372399 auto* cmb = &handle.combo();
1131 17372399 bool done = false;
1132 17372399 std::set<int32_t> visited;
1133
2/2
✓ Branch 0 taken 17372399 times.
✓ Branch 1 taken 17372399 times.
34744798 while(!done)
1134 {
1135
2/4
✓ Branch 0 taken 17372399 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17372399 times.
17372399 if(visited.contains(cid))
1136 {
1137 Z_error("Combo '%d' was part of an infinite trigger loop, breaking out of loop", cid);
1138 break; // prevent infinite loop
1139 }
1140
1/2
✓ Branch 0 taken 17372399 times.
✗ Branch 1 not taken.
17372399 visited.insert(cid);
1141
1142 17372399 done = true; // don't loop again unless something changes
1143
1/2
✓ Branch 0 taken 17372399 times.
✗ Branch 1 not taken.
17964354 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
1144 591955 return trig.trigger_flags.get(TRIGFLAG_SCREENLOAD);
1145 });
1146
2/4
✓ Branch 0 taken 17372399 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17372399 times.
17372399 if(handle.data() != cid)
1147 {
1148 cid = handle.data();
1149 cmb = &handle.combo();
1150 done = false; // loop again for the new combo
1151 }
1152 }
1153 17372399 }
1154 51768 static void handle_screen_load_trigger(const screen_handles_t& screen_handles)
1155 {
1156 51768 for_every_combo_in_screen(screen_handles, _handle_screen_load_trigger);
1157 51768 }
1158 34820 void handle_region_load_trigger()
1159 {
1160
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 34668 times.
34820 if (is_in_scrolling_region())
1161 {
1162
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 19456 times.
19608 for (int screen = 0; screen < 128; screen++)
1163 {
1164
2/2
✓ Branch 0 taken 18156 times.
✓ Branch 1 taken 1300 times.
19456 if (is_in_current_region(screen))
1165 1300 handle_screen_load_trigger(create_screen_handles_one(get_scr(screen)));
1166 19456 }
1167 152 }
1168 34668 else handle_screen_load_trigger(create_screen_handles_one(get_scr(hero_screen)));
1169 34820 }
1170
1171 15800 static void apply_state_changes_to_screen(mapscr& scr, int32_t map, int32_t screen, int32_t flags, bool secrets_do_replay_comment)
1172 {
1173 15800 auto screen_handles = create_screen_handles_one(&scr);
1174
1175
3/4
✓ Branch 0 taken 539 times.
✓ Branch 1 taken 15261 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 539 times.
15800 if ((flags & mSECRET) && canPermSecret(cur_dmap, screen))
1176 {
1177 539 reveal_hidden_stairs(&scr, screen, false);
1178 539 bool do_layers = false;
1179 539 bool from_active_screen = false;
1180 539 trigger_secrets_for_screen_internal(screen_handles, do_layers, from_active_screen, -3, secrets_do_replay_comment);
1181 539 }
1182
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if (flags & mLIGHTBEAM)
1183 {
1184 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
1185 if (rpos_handle.ctype() == cLIGHTTARGET)
1186 {
1187 if (!(rpos_handle.combo().usrflags&cflag1)) //Unlit version
1188 rpos_handle.increment_data();
1189 }
1190 });
1191 }
1192
1193 15800 int lvl = DMaps[cur_dmap].level;
1194 15800 toggle_switches(game->lvlswitches[lvl], true, screen_handles);
1195 15800 toggle_gswitches_load(screen_handles);
1196
1197
2/2
✓ Branch 0 taken 15708 times.
✓ Branch 1 taken 92 times.
15800 if(flags&mLOCKBLOCK) // if special stuff done before
1198 {
1199 92 remove_screenstatecombos2(screen_handles, false, cLOCKBLOCK, cLOCKBLOCK2);
1200 92 }
1201
1202
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mBOSSLOCKBLOCK) // if special stuff done before
1203 {
1204 remove_screenstatecombos2(screen_handles, false, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
1205 }
1206
1207
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mCHEST) // if special stuff done before
1208 {
1209 remove_screenstatecombos2(screen_handles, false, cCHEST, cCHEST2);
1210 }
1211
1212
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mCHEST) // if special stuff done before
1213 {
1214 remove_screenstatecombos2(screen_handles, false, cLOCKEDCHEST, cLOCKEDCHEST2);
1215 }
1216
1217
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mBOSSCHEST) // if special stuff done before
1218 {
1219 remove_screenstatecombos2(screen_handles, false, cBOSSCHEST, cBOSSCHEST2);
1220 }
1221
1222
1223 15800 int mi = mapind(map, screen);
1224 15800 clear_xdoors_mi(screen_handles, mi);
1225 15800 clear_xstatecombos_mi(screen_handles, mi);
1226
1227 15800 handle_screen_load_trigger(screen_handles);
1228 15800 }
1229
1230 53194 std::optional<mapscr> load_temp_mapscr_and_apply_secrets(int32_t map, int32_t screen, int32_t layer, bool secrets, bool secrets_do_replay_comment)
1231 {
1232
2/4
✓ Branch 0 taken 53194 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53194 times.
53194 if (map < 0 || screen < 0)
1233 return std::nullopt;
1234
1235 53194 const mapscr* source = get_canonical_scr(map, screen);
1236
2/2
✓ Branch 0 taken 40960 times.
✓ Branch 1 taken 12234 times.
53194 if (!source->is_valid())
1237 12234 return std::nullopt;
1238
1239
2/2
✓ Branch 0 taken 8308 times.
✓ Branch 1 taken 32652 times.
40960 if (layer >= 0)
1240 {
1241
2/2
✓ Branch 0 taken 25160 times.
✓ Branch 1 taken 7492 times.
32652 if (source->layermap[layer] <= 0)
1242 25160 return std::nullopt;
1243
1244 7492 source = get_canonical_scr(source->layermap[layer] - 1, source->layerscreen[layer]);
1245
1/2
✓ Branch 0 taken 7492 times.
✗ Branch 1 not taken.
7492 if (!source->is_valid())
1246 return std::nullopt;
1247 7492 }
1248
1249
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 int flags = secrets ? game->maps[mapind(map, screen)] : 0;
1250 15800 mapscr scr = *source;
1251
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15800 times.
15800 apply_state_changes_to_screen(scr, map, screen, flags, secrets_do_replay_comment);
1252
1253 15800 return scr;
1254 53194 }
1255
1256 27203 static int32_t MAPCOMBO3_impl(int32_t map, int32_t screen, int32_t layer, int32_t pos, bool secrets)
1257 {
1258
2/4
✓ Branch 0 taken 27203 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27203 times.
27203 if (map < 0 || screen < 0) return 0;
1259
1260
2/4
✓ Branch 0 taken 27203 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27203 times.
27203 if(pos>175 || pos < 0)
1261 return 0;
1262
1263 // TODO: consider caching this (invalidate on any modification via scripting, or anything
1264 // `apply_state_changes_to_screen` checks).
1265
4/5
✓ Branch 0 taken 4976 times.
✓ Branch 1 taken 22227 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4976 times.
✓ Branch 4 taken 22227 times.
32179 if (auto s = load_temp_mapscr_and_apply_secrets(map, screen, layer, secrets))
1266 4976 return s->data[pos];
1267
1268 22227 return 0;
1269 27203 }
1270
1271 // Read from the current temporary screens or, if (map, screen) is not loaded,
1272 // load that screen and apply the relevant secrets before evaluating the combo at that position.
1273 137738112 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets)
1274 {
1275 DCHECK_LAYER_NEG1_INDEX(layer);
1276 DCHECK(map >= 0 && screen >= 0);
1277
1278
2/2
✓ Branch 0 taken 137710909 times.
✓ Branch 1 taken 27203 times.
137738112 if (is_in_current_region(map, screen)) return MAPCOMBO2(layer, x, y);
1279
1280 // Screen is not in the current region, so we have to load and trigger some secrets.
1281 27203 int pos = COMBOPOS(x, y);
1282 27203 return MAPCOMBO3_impl(map, screen, layer, pos, secrets);
1283 137738112 }
1284
1285 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, rpos_t rpos, bool secrets)
1286 {
1287 DCHECK_LAYER_NEG1_INDEX(layer);
1288 DCHECK(map >= 0 && screen >= 0);
1289 DCHECK(is_valid_rpos(rpos));
1290
1291 if (is_in_current_region(map, screen)) return MAPCOMBO(get_rpos_handle(rpos, layer + 1));
1292
1293 // Screen is not currently loaded, so we have to load and trigger some secrets.
1294 return MAPCOMBO3_impl(map, screen, layer, RPOS_TO_POS(rpos), secrets);
1295 }
1296
1297 int32_t MAPCSET2(int32_t layer,int32_t x,int32_t y)
1298 {
1299 DCHECK_LAYER_NEG1_INDEX(layer);
1300 if (!is_in_world_bounds(x, y))
1301 return 0;
1302 if (layer == -1) return MAPCSET(x, y);
1303
1304 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1305 if (!rpos_handle.scr->is_valid()) return 0;
1306
1307 return rpos_handle.cset();
1308 }
1309
1310 98920838 int32_t MAPFLAG2(int32_t layer,int32_t x,int32_t y)
1311 {
1312 DCHECK_LAYER_NEG1_INDEX(layer);
1313
3/4
✓ Branch 0 taken 1894252 times.
✓ Branch 1 taken 97026586 times.
✓ Branch 2 taken 1894252 times.
✗ Branch 3 not taken.
98920838 if (!get_qr(qr_BUGGED_LAYERED_FLAGS) && (!is_in_world_bounds(x, y)))
1314 return 0;
1315
2/2
✓ Branch 0 taken 81313609 times.
✓ Branch 1 taken 17607229 times.
98920838 if (layer == -1) return MAPFLAG(x, y);
1316
1317 81313609 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1318
2/2
✓ Branch 0 taken 63007039 times.
✓ Branch 1 taken 18306570 times.
81313609 if (!rpos_handle.scr->is_valid()) return 0;
1319
1320 18306570 return rpos_handle.sflag();
1321 98920838 }
1322
1323 int32_t COMBOTYPE2(int32_t layer,int32_t x,int32_t y)
1324 {
1325 if(layer < 1)
1326 {
1327 for (int32_t i = layer+1; i <= 1; ++i)
1328 {
1329 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1330 {
1331 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1332 }
1333 else
1334 {
1335 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1336 }
1337 }
1338 }
1339 if(layer==-1) return COMBOTYPE(x,y);
1340
1341 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1342 if (!rpos_handle.scr->is_valid()) return 0;
1343
1344 return rpos_handle.ctype();
1345 }
1346
1347 // Returns the flag for the combo at the given position.
1348 // This is also known as an "inherent flag".
1349 97151985 int32_t MAPCOMBOFLAG2(int32_t layer,int32_t x,int32_t y)
1350 {
1351 DCHECK_LAYER_NEG1_INDEX(layer);
1352
2/2
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 97151697 times.
97151985 if (!is_in_world_bounds(x, y))
1353 288 return 0;
1354
2/2
✓ Branch 0 taken 81255084 times.
✓ Branch 1 taken 15896613 times.
97151697 if (layer == -1) return MAPCOMBOFLAG(x, y);
1355
1356 81255084 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1357
2/2
✓ Branch 0 taken 63016952 times.
✓ Branch 1 taken 18238132 times.
81255084 if (!rpos_handle.scr->is_valid()) return 0;
1358
1359 18238132 return rpos_handle.cflag();
1360 97151985 }
1361
1362 11626947 bool HASFLAG(int32_t flag, int32_t layer, rpos_t rpos)
1363 {
1364 DCHECK_LAYER_ZERO_INDEX(layer);
1365 11626947 auto rpos_handle = get_rpos_handle(rpos, layer);
1366
2/2
✓ Branch 0 taken 6436552 times.
✓ Branch 1 taken 5190395 times.
11626947 if (!rpos_handle.scr->is_valid()) return false;
1367
2/2
✓ Branch 0 taken 4565 times.
✓ Branch 1 taken 5185830 times.
5190395 if (rpos_handle.sflag() == flag) return true;
1368
2/2
✓ Branch 0 taken 37705 times.
✓ Branch 1 taken 5148125 times.
5185830 if (rpos_handle.cflag() == flag) return true;
1369 5148125 return false;
1370 11626947 }
1371
1372 1697077 bool HASFLAG_ANY(int32_t flag, rpos_t rpos)
1373 {
1374 DCHECK(is_valid_rpos(rpos));
1375
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1697077 times.
1697077 if (rpos > region_max_rpos) return false;
1376
1377
2/2
✓ Branch 0 taken 11626947 times.
✓ Branch 1 taken 1654807 times.
13281754 for(auto q = 0; q < 7; ++q)
1378 {
1379
2/2
✓ Branch 0 taken 42270 times.
✓ Branch 1 taken 11584677 times.
11626947 if(HASFLAG(flag, q, rpos))
1380 42270 return true;
1381 11584677 }
1382 1654807 return false;
1383 1697077 }
1384
1385 const char *screenstate_string[32] =
1386 {
1387 "Door Up", "Door Down", "Door Left", "Door Right", "Item", "Special Item", "Some Enemies Never Return",
1388 "Temporary No Return", "Lock Blocks", "Boss Lock Blocks", "Chests", "Locked Chests",
1389 "Boss Locked Chests", "Secrets", "Visited", "Light Beams",
1390 "All Enemies Don't Return", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1391 "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1392 };
1393
1394 34860 void eventlog_mapflags()
1395 {
1396 34860 std::ostringstream oss;
1397
1398 34860 int mi = mapind(cur_map, home_screen);
1399
1/2
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
34860 dword g = game->maps[mi];
1400
1401
2/4
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 34860 times.
✗ Branch 3 not taken.
34860 oss << fmt::format("Screen ({}, {:02X})", cur_map+1, home_screen);
1402
2/2
✓ Branch 0 taken 14514 times.
✓ Branch 1 taken 20346 times.
34860 if(g) // Main States
1403 {
1404 static const int order[] =
1405 {
1406 mSECRET, mITEM, mSPECIALITEM, mLOCKBLOCK, mBOSSLOCKBLOCK,
1407 mCHEST, mLOCKEDCHEST, mBOSSCHEST,
1408 mDOOR_UP, mDOOR_DOWN, mDOOR_LEFT, mDOOR_RIGHT,
1409 mNEVERRET, mTMPNORET, mLIGHTBEAM, mNO_ENEMIES_RETURN
1410 };
1411
1412
1/2
✓ Branch 0 taken 14514 times.
✗ Branch 1 not taken.
14514 oss << " [";
1413 14514 bool comma = false;
1414
2/2
✓ Branch 0 taken 14514 times.
✓ Branch 1 taken 232224 times.
246738 for(int fl : order)
1415 {
1416
2/2
✓ Branch 0 taken 8979 times.
✓ Branch 1 taken 223245 times.
232224 if(!(g&fl))
1417 223245 continue;
1418 8979 byte ind = byte(log2(double(fl)));
1419
2/2
✓ Branch 0 taken 1922 times.
✓ Branch 1 taken 7057 times.
8979 if(comma)
1420
1/2
✓ Branch 0 taken 1922 times.
✗ Branch 1 not taken.
1922 oss << ", ";
1421
1/2
✓ Branch 0 taken 8979 times.
✗ Branch 1 not taken.
8979 oss << screenstate_string[ind];
1422 8979 comma = true;
1423 }
1424
1/2
✓ Branch 0 taken 14514 times.
✗ Branch 1 not taken.
14514 oss << "]";
1425 14514 }
1426
3/4
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 34822 times.
34860 if(game->xstates[mi]) // ExStates
1427 {
1428
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 oss << " Ex[";
1429 38 bool comma = false;
1430
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 1216 times.
1254 for(byte fl = 0; fl < 32; ++fl)
1431 {
1432
3/4
✓ Branch 0 taken 1216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 1172 times.
1216 if(game->xstates[mi] & (1<<fl))
1433 {
1434
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 38 times.
44 if(comma)
1435
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 oss << ", ";
1436
1/2
✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
44 oss << int(fl);
1437 44 comma = true;
1438 44 }
1439 1216 }
1440
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 oss << "]";
1441 38 }
1442 { // ExDoors
1443
2/2
✓ Branch 0 taken 34860 times.
✓ Branch 1 taken 139440 times.
174300 for(int q = 0; q < 4; ++q)
1444 {
1445 139440 bool comma = false;
1446
3/4
✓ Branch 0 taken 139440 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 139438 times.
✓ Branch 3 taken 2 times.
139440 if(auto v = game->xdoors[mi][q])
1447 {
1448
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(comma)
1449 oss << ",";
1450
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 else oss << " ExDoor";
1451
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 oss << "[" << dirstr[q];
1452
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16 times.
18 for(int fl = 0; fl < 8; ++fl)
1453
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3 times.
19 if(v & (1<<fl))
1454
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 oss << " " << int(fl);
1455
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 oss << "]";
1456 2 comma = true;
1457 2 }
1458 139440 }
1459 }
1460
2/4
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 34860 times.
34860 Z_eventlog("%s\n", oss.str().c_str());
1461 34860 }
1462
1463 // set specific flag
1464 5616 void setmapflag(mapscr* scr, uint32_t flag)
1465 {
1466
2/2
✓ Branch 0 taken 5603 times.
✓ Branch 1 taken 13 times.
5616 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1467 5616 int mi = mapind(cur_map, scr->screen);
1468 5616 setmapflag_mi(scr, mi, flag);
1469 5616 }
1470 57 void setmapflag_homescr(uint32_t flag)
1471 {
1472 57 int mi = mapind(cur_map, home_screen);
1473 57 setmapflag_mi(origin_scr, mi, flag);
1474 57 }
1475 2023 void setmapflag_mi(int32_t mi, uint32_t flag)
1476 {
1477 2023 byte cscr = mi&((1<<7)-1);
1478 2023 byte cmap = (mi>>7);
1479 2023 mapscr* scr = origin_scr;
1480
2/2
✓ Branch 0 taken 834 times.
✓ Branch 1 taken 1189 times.
2023 if (is_in_current_region(cmap, cscr))
1481 1189 scr = get_scr(cmap, cscr);
1482
1483 2023 setmapflag_mi(scr, mi, flag);
1484 2023 }
1485
1486 8478 static void log_state_change(int map, int screen, std::string action)
1487 {
1488
6/6
✓ Branch 0 taken 1913 times.
✓ Branch 1 taken 6565 times.
✓ Branch 2 taken 996 times.
✓ Branch 3 taken 917 times.
✓ Branch 4 taken 352 times.
✓ Branch 5 taken 644 times.
8478 if (is_in_current_region(map, screen) || (map == cur_map && screen == home_screen))
1489 6917 Z_eventlog("[Map %d, Screen %02X (current)] %s\n", map + 1, screen, action.c_str());
1490 else
1491 1561 Z_eventlog("[Map %d, Screen %02X] %s\n", map + 1, screen, action.c_str());
1492 8478 }
1493
1494 7696 void setmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag)
1495 {
1496 7696 byte cscr = mi&((1<<7)-1);
1497 7696 byte cmap = (mi>>7);
1498
1499 7696 double temp=log2((double)flag);
1500
1/2
✓ Branch 0 taken 7696 times.
✗ Branch 1 not taken.
7696 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1501 7696 const char* replay_state_string = state_string;
1502
2/2
✓ Branch 0 taken 7176 times.
✓ Branch 1 taken 520 times.
7696 if(temp == 6) replay_state_string = "No Return";
1503
1504
3/4
✓ Branch 0 taken 7696 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1552 times.
✓ Branch 3 taken 6144 times.
7696 if (replay_is_active() && !(game->maps[mi] & flag))
1505
1/2
✓ Branch 0 taken 6144 times.
✗ Branch 1 not taken.
6144 replay_step_comment(fmt::format("map {} scr {} flag {}", cmap, cscr, replay_state_string));
1506 7696 game->maps[mi] |= flag;
1507
1/2
✓ Branch 0 taken 7696 times.
✗ Branch 1 not taken.
7696 log_state_change(cmap, cscr, fmt::format("State set: {}", state_string));
1508
1509
2/2
✓ Branch 0 taken 2507 times.
✓ Branch 1 taken 5189 times.
7696 if((scr->nocarry&flag)!=flag)
1510 {
1511 5189 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1512 5189 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1513
1514 5189 std::vector<int32_t> done;
1515
2/2
✓ Branch 0 taken 5094 times.
✓ Branch 1 taken 95 times.
5189 bool looped = (nmap==cmap+1 && nscr==cscr);
1516
1517
6/6
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 5147 times.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 364 times.
✓ Branch 4 taken 364 times.
✓ Branch 5 taken 5189 times.
5553 while((nmap!=0) && !looped && !(nscr>=128))
1518 {
1519
3/4
✓ Branch 0 taken 364 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 171 times.
✓ Branch 3 taken 193 times.
364 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1520 {
1521
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 log_state_change(nmap, nscr, "State change carried over");
1522
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 if (replay_is_active())
1523
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 replay_step_comment(fmt::format("map {} scr {} flag {} carry", nmap, nscr, replay_state_string));
1524
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 game->maps[((nmap-1)<<7)+nscr] |= flag;
1525 193 }
1526
1527 364 cmap=nmap;
1528 364 cscr=nscr;
1529 364 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1530 364 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1531
1532
2/2
✓ Branch 0 taken 889 times.
✓ Branch 1 taken 364 times.
1253 for(auto it = done.begin(); it != done.end(); it++)
1533 {
1534
2/2
✓ Branch 0 taken 847 times.
✓ Branch 1 taken 42 times.
889 if(*it == ((nmap-1)<<7)+nscr)
1535 42 looped = true;
1536 889 }
1537
1538
1/2
✓ Branch 0 taken 364 times.
✗ Branch 1 not taken.
364 done.push_back(((nmap-1)<<7)+nscr);
1539 }
1540 5189 }
1541 7696 }
1542
1543 void unsetmapflag_home(uint32_t flag, bool anyflag)
1544 {
1545 int mi = mapind(cur_map, home_screen);
1546 unsetmapflag_mi(origin_scr, mi, flag, anyflag);
1547 }
1548
1549 void unsetmapflag(mapscr* scr, uint32_t flag, bool anyflag)
1550 {
1551 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1552 int mi = mapind(cur_map, scr->screen);
1553 unsetmapflag_mi(scr, mi, flag, anyflag);
1554 }
1555
1556 471 void unsetmapflag_mi(int32_t mi, uint32_t flag, bool anyflag)
1557 {
1558 471 byte cscr = mi&((1<<7)-1);
1559 471 byte cmap = (mi>>7);
1560 471 mapscr* scr = origin_scr;
1561
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if (is_in_current_region(cmap, cscr))
1562 11 scr = get_scr(cmap, cscr);
1563
1564 471 unsetmapflag_mi(scr, mi, flag, anyflag);
1565 471 }
1566
1567 471 void unsetmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag, bool anyflag)
1568 {
1569 471 byte cscr = mi&((1<<7)-1);
1570 471 byte cmap = (mi>>7);
1571
1572
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if(anyflag)
1573 460 game->maps[mi] &= ~flag;
1574
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 else if(flag==mITEM || flag==mSPECIALITEM)
1575 {
1576 if(!(scr->flags4&fNOITEMRESET))
1577 game->maps[mi] &= ~flag;
1578 }
1579 11 else game->maps[mi] &= ~flag;
1580
1581 471 double temp=log2((double)flag);
1582
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1583
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 log_state_change(cmap, cscr, fmt::format("State unset: {}", state_string));
1584
1585
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 471 times.
471 if((scr->nocarry&flag)!=flag)
1586 {
1587 471 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1588 471 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1589
1590 471 std::vector<int32_t> done;
1591
2/2
✓ Branch 0 taken 466 times.
✓ Branch 1 taken 5 times.
471 bool looped = (nmap==cmap+1 && nscr==cscr);
1592
1593
6/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 465 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 471 times.
555 while((nmap!=0) && !looped && !(nscr>=128))
1594 {
1595
3/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 72 times.
84 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1596 {
1597
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 log_state_change(nmap, nscr, "State change carried over");
1598
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 game->maps[((nmap-1)<<7)+nscr] &= ~flag;
1599 72 }
1600
1601 84 cmap=nmap;
1602 84 cscr=nscr;
1603 84 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1604 84 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1605
1606
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 546 times.
630 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1607 {
1608
2/2
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 6 times.
546 if(*it == ((nmap-1)<<7)+nscr)
1609 6 looped = true;
1610 546 }
1611
1612
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 done.push_back(((nmap-1)<<7)+nscr);
1613 }
1614 471 }
1615 471 }
1616
1617 50173955 bool getmapflag(int32_t screen, uint32_t flag)
1618 {
1619
2/2
✓ Branch 0 taken 1345925 times.
✓ Branch 1 taken 48828030 times.
50173955 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1620 50173955 return (game->maps[mi] & flag) != 0;
1621 }
1622 6228660 bool getmapflag(mapscr* scr, uint32_t flag)
1623 {
1624 6228660 return getmapflag(scr->screen, flag);
1625 }
1626
1627 60 void setxmapflag(int32_t screen, uint32_t flag)
1628 {
1629
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60 times.
60 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1630 60 setxmapflag_mi(mi, flag);
1631 60 }
1632 62 void setxmapflag_mi(int32_t mi, uint32_t flag)
1633 {
1634
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 41 times.
62 if(game->xstates[mi] & flag) return;
1635 41 byte cscr = mi&((1<<7)-1);
1636 41 byte cmap = (mi>>7);
1637
1638 41 byte temp=(byte)log2((double)flag);
1639
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 log_state_change(cmap, cscr, fmt::format("ExtraState set: {}", temp));
1640
1641 41 game->xstates[mi] |= flag;
1642
1643 41 mapscr* scr = origin_scr;
1644
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 if (is_in_current_region(cmap, cscr))
1645 41 scr = get_scr(cmap, cscr);
1646
1647
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 if((scr->exstate_carry&flag)==flag)
1648 {
1649 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1650 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1651
1652 std::vector<int32_t> done;
1653 bool looped = (nmap==cmap+1 && nscr==cscr);
1654
1655 while((nmap!=0) && !looped && !(nscr>=128))
1656 {
1657 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1658 {
1659 log_state_change(nmap, nscr, "ExState change carried over");
1660 if (replay_is_active())
1661 replay_step_comment(fmt::format("map {} scr {} exstate {} carry", nmap, nscr, temp));
1662 game->xstates[((nmap-1)<<7)+nscr] |= flag;
1663 }
1664
1665 cmap=nmap;
1666 cscr=nscr;
1667 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1668 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1669
1670 for(auto it = done.begin(); it != done.end(); it++)
1671 {
1672 if(*it == ((nmap-1)<<7)+nscr)
1673 looped = true;
1674 }
1675
1676 done.push_back(((nmap-1)<<7)+nscr);
1677 }
1678 }
1679 62 }
1680 2 void unsetxmapflag(int32_t screen, uint32_t flag)
1681 {
1682
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1683 2 unsetxmapflag_mi(mi, flag);
1684 2 }
1685 2 void unsetxmapflag_mi(int32_t mi, uint32_t flag)
1686 {
1687
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(!(game->xstates[mi] & flag)) return;
1688 1 byte cscr = mi&((1<<7)-1);
1689 1 byte cmap = (mi>>7);
1690 1 byte temp=(byte)log2((double)flag);
1691
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 log_state_change(cmap, cscr, fmt::format("ExtraState unset: {}", temp));
1692 1 game->xstates[mi] &= ~flag;
1693
1694 1 mapscr* scr = origin_scr;
1695
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (is_in_current_region(cmap, cscr))
1696 1 scr = get_scr(cmap, cscr);
1697
1698
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if((scr->exstate_carry&flag)==flag)
1699 {
1700 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1701 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1702
1703 std::vector<int32_t> done;
1704 bool looped = (nmap==cmap+1 && nscr==cscr);
1705
1706 while((nmap!=0) && !looped && !(nscr>=128))
1707 {
1708 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1709 {
1710 log_state_change(nmap, nscr, "ExState change carried over");
1711 game->xstates[((nmap-1)<<7)+nscr] &= ~flag;
1712 }
1713
1714 cmap=nmap;
1715 cscr=nscr;
1716 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1717 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1718
1719 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1720 {
1721 if(*it == ((nmap-1)<<7)+nscr)
1722 looped = true;
1723 }
1724
1725 done.push_back(((nmap-1)<<7)+nscr);
1726 }
1727 }
1728 2 }
1729 34 bool getxmapflag(int32_t screen, uint32_t flag)
1730 {
1731
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1732 34 return getxmapflag_mi(mi, flag);
1733 }
1734 471496240 bool getxmapflag_mi(int32_t mi, uint32_t flag)
1735 {
1736 471496240 return (game->xstates[mi] & flag) != 0;
1737 }
1738
1739 4 void setxdoor_mi(uint mi, uint dir, uint ind, bool state)
1740 {
1741
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 if(mi > game->xdoors.size() || dir > 3 || ind > 8)
1742 return;
1743
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(!(game->xdoors[mi][dir] & (1<<ind)) == !state)
1744 return;
1745
1746
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 SETFLAG(game->xdoors[mi][dir], 1<<ind, state);
1747
1748 4 int cscr = mi % MAPSCRSNORMAL;
1749 4 int cmap = mi / MAPSCRSNORMAL;
1750
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (state)
1751
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] set", dirstr[dir], ind));
1752 else
1753 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] unset", dirstr[dir], ind));
1754 4 }
1755 471496201 bool getxdoor_mi(uint mi, uint dir, uint ind)
1756 {
1757
3/6
✓ Branch 0 taken 471496201 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 471496201 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 471496201 times.
471496201 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1758 return false;
1759 471496201 return (game->xdoors[mi][dir] & (1<<ind));
1760 471496201 }
1761 9 bool getxdoor(int32_t screen, uint dir, uint ind)
1762 {
1763 9 int mi = mapind(cur_map, screen);
1764 9 return getxdoor_mi(mi,dir,ind);
1765 }
1766
1767 401 void set_doorstate_mi(uint mi, uint dir)
1768 {
1769
1/2
✓ Branch 0 taken 401 times.
✗ Branch 1 not taken.
401 if(dir >= 4)
1770 return;
1771 401 setmapflag_mi(mi, mDOOR_UP << dir);
1772
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 400 times.
401 if(auto di = nextscr_mi(mi, dir))
1773 400 setmapflag_mi(*di, mDOOR_UP << oppositeDir[dir]);
1774 401 }
1775 401 void set_doorstate(uint screen, uint dir)
1776 {
1777 401 int mi = mapind(cur_map, screen);
1778 401 set_doorstate_mi(mi, dir);
1779 401 }
1780
1781 2 void set_xdoorstate_mi(uint mi, uint dir, uint ind, bool state)
1782 {
1783
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1784 return;
1785 2 setxdoor_mi(mi, dir, ind, state);
1786
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(auto di = nextscr_mi(mi, dir))
1787 2 setxdoor_mi(*di, oppositeDir[dir], ind, state);
1788 2 }
1789
1790 2 void set_xdoorstate(int32_t screen,uint dir, uint ind, bool state)
1791 {
1792 2 int mi = mapind(cur_map, screen);
1793 2 set_xdoorstate_mi(mi, dir, ind, state);
1794 2 }
1795
1796 57 int32_t WARPCODE(int32_t dmap,int32_t screen,int32_t dw)
1797 // returns: -1 = not a warp screen
1798 // 0+ = warp screen code ( high byte=dmap, low byte=scr )
1799 {
1800 57 const mapscr *scr = get_canonical_scr(DMaps[dmap].map, screen);
1801
1802
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(scr->room!=rWARP)
1803 return -1;
1804
1805 57 int32_t ring=scr->catchall;
1806 57 int32_t size=QMisc.warp[ring].size;
1807
1808
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 if(size==0)
1809 return -2;
1810
1811 57 int32_t index=-1;
1812
1813
2/2
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 57 times.
346 for(int32_t i=0; i<size; i++)
1814
6/6
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 173 times.
✓ Branch 3 taken 57 times.
✓ Branch 4 taken 173 times.
✓ Branch 5 taken 57 times.
289 if(dmap==QMisc.warp[ring].dmap[i] && screen==
1815 346 (QMisc.warp[ring].scr[i] + DMaps[dmap].xoff))
1816 57 index=i;
1817
1818
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(index==-1)
1819 return -3;
1820
1821 57 index = (index+dw)%size;
1822 57 return (QMisc.warp[ring].dmap[index] << 8) + QMisc.warp[ring].scr[index];
1823 57 }
1824
1825 14779694 void update_combo_cycling()
1826 {
1827 14779694 auto& combo_cache = combo_caches::can_cycle;
1828
1829 static int32_t newdata[176];
1830 static int32_t newcset[176];
1831 static bool initialized=false;
1832
1833 // Just a simple bit of optimization
1834
2/2
✓ Branch 0 taken 14779383 times.
✓ Branch 1 taken 311 times.
14779694 if(!initialized)
1835 {
1836
2/2
✓ Branch 0 taken 54736 times.
✓ Branch 1 taken 311 times.
55047 for(int32_t i=0; i<176; i++)
1837 {
1838 54736 newdata[i]=-1;
1839 54736 newcset[i]=-1;
1840 54736 }
1841
1842 311 initialized=true;
1843 311 }
1844
1845 14779694 std::set<uint16_t> restartanim;
1846
1847
1/2
✓ Branch 0 taken 14779694 times.
✗ Branch 1 not taken.
29948756 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
1848 15169062 int screen = scr->screen;
1849 int32_t x;
1850
1851
2/2
✓ Branch 0 taken 2669754912 times.
✓ Branch 1 taken 15169062 times.
2684923974 for(int32_t i=0; i<176; i++)
1852 {
1853 2669754912 x=scr->data[i];
1854 2669754912 auto& mini_cmb = combo_cache.minis[x];
1855
2/2
✓ Branch 0 taken 3273932 times.
✓ Branch 1 taken 2666480980 times.
2669754912 if (!mini_cmb.can_cycle)
1856 2666480980 continue;
1857
1858 3273932 newcombo const& cmb = combobuf[x];
1859
1860 //time to restart
1861
4/4
✓ Branch 0 taken 902694 times.
✓ Branch 1 taken 2371238 times.
✓ Branch 2 taken 474434 times.
✓ Branch 3 taken 428260 times.
3273932 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1862 {
1863 428260 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1864
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428260 times.
428260 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1865 428260 newdata[i] = c;
1866
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428240 times.
428260 if(!(cmb.animflags & AF_CYCLENOCSET))
1867
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428240 times.
428240 newcset[i] = cycle_under ? scr->undercset : cmb.nextcset;
1868
1869
2/2
✓ Branch 0 taken 427216 times.
✓ Branch 1 taken 1044 times.
428260 if(combobuf[c].animflags & AF_CYCLE)
1870 {
1871 1044 restartanim.insert(c);
1872 1044 }
1873 428260 }
1874 3273932 }
1875
1876 15169062 int rpos_base = (int)POS_TO_RPOS(0, region_scr_x, region_scr_y);
1877
2/2
✓ Branch 0 taken 2669754912 times.
✓ Branch 1 taken 15169062 times.
2684923974 for(int32_t i=0; i<176; i++)
1878 {
1879
2/2
✓ Branch 0 taken 428260 times.
✓ Branch 1 taken 2669326652 times.
2669754912 if(newdata[i]==-1)
1880 2669326652 continue;
1881
1882 428260 rpos_t rpos = (rpos_t)(rpos_base + i);
1883 428260 rpos_handle_t rpos_handle = {scr, screen, 0, rpos, i};
1884 428260 screen_combo_modify_preroutine(rpos_handle);
1885 428260 scr->data[i]=newdata[i];
1886
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428240 times.
428260 if(newcset[i]>-1)
1887 428240 scr->cset[i]=newcset[i];
1888 428260 screen_combo_modify_postroutine(rpos_handle);
1889
1890 428260 newdata[i]=-1;
1891 428260 newcset[i]=-1;
1892 428260 }
1893
1894 15169062 word c = scr->numFFC();
1895
2/2
✓ Branch 0 taken 15169062 times.
✓ Branch 1 taken 453640163 times.
468809225 for(word i=0; i<c; i++)
1896 {
1897 453640163 ffcdata& ffc = scr->ffcs[i];
1898 453640163 auto& mini_cmb = combo_cache.minis[ffc.data];
1899
2/2
✓ Branch 0 taken 4173 times.
✓ Branch 1 taken 453635990 times.
453640163 if (!mini_cmb.can_cycle)
1900 453635990 continue;
1901
1902 4173 newcombo const& cmb = combobuf[ffc.data];
1903
1904 //time to restart
1905
4/4
✓ Branch 0 taken 611 times.
✓ Branch 1 taken 3562 times.
✓ Branch 2 taken 503 times.
✓ Branch 3 taken 108 times.
4173 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1906 {
1907 108 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1908
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1909 108 zc_ffc_set(ffc, c);
1910
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if(!(cmb.animflags & AF_CYCLENOCSET))
1911
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 ffc.cset = cycle_under ? scr->undercset : cmb.nextcset;
1912
1913
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 60 times.
108 if(combobuf[ffc.data].animflags & AF_CYCLE)
1914 {
1915 60 restartanim.insert(ffc.data);
1916 60 }
1917 108 }
1918 4173 }
1919
1920
2/2
✓ Branch 0 taken 8418399 times.
✓ Branch 1 taken 6750663 times.
15169062 if(get_qr(qr_CMBCYCLELAYERS))
1921 {
1922
2/2
✓ Branch 0 taken 40503978 times.
✓ Branch 1 taken 6750663 times.
47254641 for(int32_t j=1; j<=6; j++)
1923 {
1924 40503978 mapscr* layer_scr = get_scr_layer_valid(screen, j);
1925
2/2
✓ Branch 0 taken 10894345 times.
✓ Branch 1 taken 29609633 times.
40503978 if (!layer_scr)
1926 29609633 continue;
1927
1928
2/2
✓ Branch 0 taken 1917404720 times.
✓ Branch 1 taken 10894345 times.
1928299065 for(int32_t i=0; i<176; i++)
1929 {
1930 1917404720 x=layer_scr->data[i];
1931 1917404720 auto& mini_cmb = combo_cache.minis[x];
1932
2/2
✓ Branch 0 taken 2230074 times.
✓ Branch 1 taken 1915174646 times.
1917404720 if (!mini_cmb.can_cycle)
1933 1915174646 continue;
1934
1935 2230074 newcombo const& cmb = combobuf[x];
1936
1937 //time to restart
1938
4/4
✓ Branch 0 taken 48416 times.
✓ Branch 1 taken 2181658 times.
✓ Branch 2 taken 37483 times.
✓ Branch 3 taken 10933 times.
2230074 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1939 {
1940 10933 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1941
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10933 times.
10933 auto c = cycle_under ? layer_scr->undercombo : cmb.nextcombo;
1942 10933 newdata[i] = c;
1943
2/2
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 10864 times.
10933 if(!(cmb.animflags & AF_CYCLENOCSET))
1944
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10864 times.
10864 newcset[i] = cycle_under ? layer_scr->undercset : cmb.nextcset;
1945 69 else newcset[i] = layer_scr->cset[i];
1946
1947
2/2
✓ Branch 0 taken 950 times.
✓ Branch 1 taken 9983 times.
10933 if(combobuf[c].animflags & AF_CYCLE)
1948 {
1949 9983 restartanim.insert(c);
1950 9983 }
1951 10933 }
1952 2230074 }
1953
1954
2/2
✓ Branch 0 taken 1917404720 times.
✓ Branch 1 taken 10894345 times.
1928299065 for (int32_t i=0; i<176; i++)
1955 {
1956
2/2
✓ Branch 0 taken 1917393787 times.
✓ Branch 1 taken 10933 times.
1917404720 if(newdata[i]!=-1)
1957 {
1958 10933 layer_scr->data[i]=newdata[i];
1959
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10933 times.
10933 if(newcset[i]>-1)
1960 10933 layer_scr->cset[i]=newcset[i];
1961 10933 newdata[i]=-1;
1962 10933 newcset[i]=-1;
1963 10933 }
1964 1917404720 }
1965 10894345 }
1966 6750663 }
1967 15169062 });
1968
1969
2/2
✓ Branch 0 taken 14779694 times.
✓ Branch 1 taken 2661 times.
14782355 for (auto i : restartanim)
1970 {
1971 2661 combobuf[i].tile = combobuf[i].o_tile;
1972 2661 combobuf[i].cur_frame=0;
1973 2661 combobuf[i].aclk = 0;
1974
1/2
✓ Branch 0 taken 2661 times.
✗ Branch 1 not taken.
2661 combo_caches::drawing.refresh(i);
1975 }
1976 14779694 }
1977
1978 1209948096 bool iswater_type(int32_t type)
1979 {
1980 // return type==cOLD_WATER || type==cSWIMWARP || type==cDIVEWARP || type==cDIVEWARPB || type==cDIVEWARPC || type==cDIVEWARPD || type==cSWIMWARPB || type==cSWIMWARPC || type==cSWIMWARPD;
1981 1209948096 return (combo_class_buf[type].water!=0);
1982 }
1983
1984 bool iswater(int32_t combo)
1985 {
1986 return iswater_type(combobuf[combo].type) && !DRIEDLAKE;
1987 }
1988 1135408 int32_t iswaterexzq(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck)
1989 {
1990 1135408 return iswaterex(combo, map, screen, layer, x, y, secrets, fullcheck, LayerCheck);
1991 }
1992
1993 // (x, y) are world coordinates
1994 58744740 int32_t iswaterex_z3(int32_t combo, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
1995 {
1996
8/8
✓ Branch 0 taken 58698589 times.
✓ Branch 1 taken 46151 times.
✓ Branch 2 taken 58658257 times.
✓ Branch 3 taken 40332 times.
✓ Branch 4 taken 58591511 times.
✓ Branch 5 taken 66746 times.
✓ Branch 6 taken 59577 times.
✓ Branch 7 taken 58531934 times.
58744740 if (x<0 || x>=world_w || y<0 || y>=world_h)
1997 212806 return false;
1998
1999 58531934 return iswaterex(combo, cur_map, cur_screen, layer, x, y, secrets, fullcheck, LayerCheck, ShallowCheck, hero, out_handle);
2000 58744740 }
2001
2002 97205668 int32_t iswaterex(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
2003 {
2004 DCHECK_LAYER_NEG1_INDEX(layer);
2005 //Honestly, fullcheck is kinda useless... I made this function back when I thought it was checking the entire combo and not just a glorified x/y value.
2006 //Fullcheck makes no sense to ever be on, but hey I guess it's here in case you ever need it...
2007
2008 //Oh hey, Zoras might actually need it. Nevermind, this had a use!
2009
2/2
✓ Branch 0 taken 57356207 times.
✓ Branch 1 taken 39849461 times.
97205668 if (get_qr(qr_SMARTER_WATER))
2010 {
2011
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 57356207 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
57356207 if (DRIEDLAKE) return 0;
2012
5/6
✓ Branch 0 taken 19560258 times.
✓ Branch 1 taken 37795949 times.
✓ Branch 2 taken 6518562 times.
✓ Branch 3 taken 13041696 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6518562 times.
57356207 if (LayerCheck && (get_qr(qr_WATER_ON_LAYER_1) || get_qr(qr_WATER_ON_LAYER_2))) //LayerCheck is a bit dumber, but it lets me add this QR without having to replace all calls, again.
2013 {
2014
2/2
✓ Branch 0 taken 37778428 times.
✓ Branch 1 taken 12368366 times.
50146794 for (int32_t m = layer; m <= 1; m++)
2015 {
2016
5/6
✓ Branch 0 taken 24736732 times.
✓ Branch 1 taken 13041696 times.
✓ Branch 2 taken 12368366 times.
✓ Branch 3 taken 12368366 times.
✓ Branch 4 taken 12368366 times.
✗ Branch 5 not taken.
50146794 if (m < 0 || m == 0 && get_qr(qr_WATER_ON_LAYER_1)
2017
1/2
✓ Branch 0 taken 12368366 times.
✗ Branch 1 not taken.
24736732 || m == 1 && get_qr(qr_WATER_ON_LAYER_2))
2018 {
2019 37778428 int32_t checkwater = iswaterex(combo, map, screen, m, x, y, secrets, fullcheck, false, ShallowCheck);
2020
2/2
✓ Branch 0 taken 37105098 times.
✓ Branch 1 taken 673330 times.
37778428 if (checkwater > 0)
2021 {
2022
2/2
✓ Branch 0 taken 673272 times.
✓ Branch 1 taken 58 times.
673330 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, m+1);
2023 673330 return checkwater;
2024 }
2025 37105098 }
2026 37105098 }
2027 12368366 return 0;
2028 }
2029 else
2030 {
2031
2/2
✓ Branch 0 taken 44329184 times.
✓ Branch 1 taken 42140357 times.
86469541 for(int32_t i=(fullcheck?3:0); i>=0; i--)
2032 {
2033 44329184 int32_t tx2=((i&2)<<2)+x;
2034 44329184 int32_t ty2=((i&1)<<3)+y;
2035 44329184 int32_t b = i; //Originally b was not needed and I read off i, but then I added the boolean for fullcheck.
2036 //In which case it's just easier to change b if fullcheck is false instead of changing i and potentially screwing up the for loop.
2037
2/2
✓ Branch 0 taken 21673 times.
✓ Branch 1 taken 44307511 times.
44329184 if (!fullcheck)
2038 {
2039 44307511 tx2 = x;
2040 44307511 ty2 = y;
2041
2/2
✓ Branch 0 taken 24876160 times.
✓ Branch 1 taken 19431351 times.
44307511 if(tx2&8) b+=2;
2042
2/2
✓ Branch 0 taken 20524614 times.
✓ Branch 1 taken 23782897 times.
44307511 if(ty2&8) b+=1;
2043 44307511 }
2044
2/2
✓ Branch 0 taken 94776242 times.
✓ Branch 1 taken 43484951 times.
138261193 for (int32_t m = layer; m <= 1; m++)
2045 {
2046 94776242 newcombo const& cmb = combobuf[MAPCOMBO3(map, screen, m,tx2,ty2, true)];
2047
2/2
✓ Branch 0 taken 17735727 times.
✓ Branch 1 taken 77040515 times.
94776242 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2048 {
2049
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17735727 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17735727 if (cmb.type == cBRIDGE && !(cmb.walk&(1<<b)))
2050 {
2051 return 0;
2052 }
2053 17735727 }
2054 else
2055 {
2056
4/4
✓ Branch 0 taken 179102 times.
✓ Branch 1 taken 76861413 times.
✓ Branch 2 taken 51152 times.
✓ Branch 3 taken 127950 times.
77040515 if (cmb.type == cBRIDGE && (cmb.walk&(0x10<<b)))
2057 {
2058 127950 return 0;
2059 }
2060 }
2061
2/2
✓ Branch 0 taken 17735727 times.
✓ Branch 1 taken 76912565 times.
94648292 if (get_qr(qr_NO_SOLID_SWIM))
2062 {
2063
8/14
✓ Branch 0 taken 51152 times.
✓ Branch 1 taken 76861413 times.
✓ Branch 2 taken 51152 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 716283 times.
✓ Branch 5 taken 76145130 times.
✓ Branch 6 taken 3461 times.
✓ Branch 7 taken 712822 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3461 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
76912565 if ((cmb.type != cBRIDGE || (!get_qr(qr_OLD_BRIDGE_COMBOS) && !(cmb.walk&(0x10<<b)))) && (cmb.walk&(1<<b)) && !((cmb.usrflags&cflag4) && cmb.type == cWATER && (cmb.walk&(0x10<<b)) && ShallowCheck))
2064 {
2065 716283 return 0;
2066 }
2067 76196282 }
2068
3/6
✓ Branch 0 taken 320336 times.
✓ Branch 1 taken 93611673 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 320336 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
93932009 if (iswater_type(cmb.type) && (cmb.walk&(1<<b)) && ((cmb.usrflags&cflag3) || (cmb.usrflags&cflag4)
2069 || (hero && current_item(itype_flippers) < cmb.attribytes[0])
2070 || (hero && ((cmb.usrflags&cflag1) && !(itemsbuf[current_item_id(itype_flippers)].flags & item_flag3)))))
2071 {
2072 if (!(ShallowCheck && (cmb.walk&(1<<b)) && (cmb.usrflags&cflag4))) return 0;
2073 }
2074 93932009 }
2075
2076 131351511 auto found_ffc_not_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2077
2/2
✓ Branch 0 taken 87338695 times.
✓ Branch 1 taken 527865 times.
87866560 if (ffcIsAt(ffc_handle, tx2, ty2))
2078 {
2079 527865 auto ty = ffc_handle.ctype();
2080
4/6
✓ Branch 0 taken 527865 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144225 times.
✓ Branch 3 taken 383640 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 144225 times.
527865 if(!combo_class_buf[ty].water && !(ShallowCheck && ty == cSHALLOWWATER))
2081 527865 return true;
2082 }
2083
2084 87338695 return false;
2085 87866560 });
2086
2/2
✓ Branch 0 taken 42957086 times.
✓ Branch 1 taken 527865 times.
43484951 if (found_ffc_not_water) return 0;
2087
2088
2/2
✓ Branch 0 taken 14673 times.
✓ Branch 1 taken 42942413 times.
42957086 if(!i)
2089 {
2090 127957187 auto found_ffc_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2091
1/2
✓ Branch 0 taken 85014774 times.
✗ Branch 1 not taken.
85014774 if (ffcIsAt(ffc_handle, tx2, ty2))
2092 {
2093 auto ty = ffc_handle.ctype();
2094 if(combo_class_buf[ty].water || (ShallowCheck && ty == cSHALLOWWATER))
2095 return true;
2096 }
2097
2098 85014774 return false;
2099 85014774 });
2100
1/2
✓ Branch 0 taken 42942413 times.
✗ Branch 1 not taken.
42942413 if (found_ffc_water)
2101 {
2102 if(out_handle) *out_handle = *found_ffc_water;
2103 return found_ffc_water->data();
2104 }
2105 42942413 }
2106
2107 42957086 int32_t checkcombo = MAPCOMBO3(map, screen, layer, tx2, ty2, secrets);
2108
2/2
✓ Branch 0 taken 42912592 times.
✓ Branch 1 taken 44494 times.
42957086 if (!(combobuf[checkcombo].walk&(1<<(b+4)))) return 0;
2109
7/12
✓ Branch 0 taken 42631987 times.
✓ Branch 1 taken 280605 times.
✓ Branch 2 taken 10830561 times.
✓ Branch 3 taken 31801426 times.
✓ Branch 4 taken 10352377 times.
✓ Branch 5 taken 478184 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 10352377 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
42912592 if (iswater_type(combobuf[checkcombo].type)||(ShallowCheck && (combobuf[checkcombo].type == cSHALLOWWATER || (iswater_type(combobuf[checkcombo].type) && (combobuf[checkcombo].walk&(1<<b)) && (combobuf[checkcombo].usrflags&cflag4)))))
2110 {
2111
2/2
✓ Branch 0 taken 1227 times.
✓ Branch 1 taken 757562 times.
758789 if (i == 0)
2112 {
2113
2/2
✓ Branch 0 taken 757553 times.
✓ Branch 1 taken 9 times.
757562 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(tx2, ty2, layer+1);
2114 757562 return checkcombo;
2115 }
2116 1227 }
2117 42155030 }
2118 42140357 return 0;
2119 }
2120 }
2121 else
2122 {
2123 39849461 int32_t b = 0;
2124
2/2
✓ Branch 0 taken 20636412 times.
✓ Branch 1 taken 19213049 times.
39849461 if(x&8) b+=2;
2125
2/2
✓ Branch 0 taken 15456485 times.
✓ Branch 1 taken 24392976 times.
39849461 if(y&8) b+=1;
2126
1/2
✓ Branch 0 taken 39849461 times.
✗ Branch 1 not taken.
39849461 if (get_qr(qr_NO_SOLID_SWIM))
2127 {
2128 if (combobuf[combo].walk&(1<<b))
2129 {
2130 return 0;
2131 }
2132 }
2133
1/2
✓ Branch 0 taken 39849461 times.
✗ Branch 1 not taken.
39849461 if (!(combobuf[combo].walk&(1<<(b+4)))) return 0;
2134
8/8
✓ Branch 0 taken 38150901 times.
✓ Branch 1 taken 1698560 times.
✓ Branch 2 taken 167945 times.
✓ Branch 3 taken 37982956 times.
✓ Branch 4 taken 2129 times.
✓ Branch 5 taken 1782338 times.
✓ Branch 6 taken 163774 times.
✓ Branch 7 taken 161691 times.
39849461 if((iswater_type(combobuf[combo].type) || (ShallowCheck && combobuf[combo].type == cSHALLOWWATER)) && !DRIEDLAKE)
2135 {
2136
2/2
✓ Branch 0 taken 1943999 times.
✓ Branch 1 taken 30 times.
1944029 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, 0); //NOTE: This is only correct assuming 'combo' is 'MAPCOMBO(x,y)'
2137 1944029 return combo;
2138 }
2139 38146730 return 0;
2140 }
2141 97446966 }
2142
2143 326 bool isdamage_type(int32_t type)
2144 {
2145
1/2
✓ Branch 0 taken 326 times.
✗ Branch 1 not taken.
326 switch(type)
2146 {
2147 case cDAMAGE1: case cDAMAGE2: case cDAMAGE3: case cDAMAGE4:
2148 case cDAMAGE5: case cDAMAGE6: case cDAMAGE7:
2149 return true;
2150 }
2151 326 return false;
2152 326 }
2153
2154 2569347297 bool ispitfall_type(int32_t type)
2155 {
2156 2569347297 return combo_class_buf[type].pit != 0;
2157 }
2158
2159 2569347297 bool ispitfall(int32_t combo)
2160 {
2161 2569347297 return ispitfall_type(combobuf[combo].type);
2162 }
2163
2164 278127958 bool ispitfall(int32_t x, int32_t y)
2165 {
2166
2/2
✓ Branch 0 taken 1456039 times.
✓ Branch 1 taken 276671919 times.
278127958 if(int32_t c = MAPFFCOMBO(x,y))
2167 {
2168 1456039 return ispitfall(c) ? true : false;
2169 }
2170 276671919 int32_t c = MAPCOMBOL(2,x,y);
2171
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 276671919 times.
276671919 if(ispitfall(c)) return true;
2172
2/2
✓ Branch 0 taken 263560767 times.
✓ Branch 1 taken 13111152 times.
276671919 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2173 {
2174
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 263560767 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
263560767 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return false;
2175 263560767 }
2176 else
2177 {
2178
3/4
✓ Branch 0 taken 2780 times.
✓ Branch 1 taken 13108372 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2780 times.
13111152 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return false;
2179 }
2180 276669139 c = MAPCOMBOL(1,x,y);
2181
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 276669115 times.
276669139 if(ispitfall(c)) return true;
2182
2183
2/2
✓ Branch 0 taken 263560767 times.
✓ Branch 1 taken 13108348 times.
276669115 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2184 {
2185
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 263560767 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
263560767 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return false;
2186 263560767 }
2187 else
2188 {
2189
4/4
✓ Branch 0 taken 13072 times.
✓ Branch 1 taken 13095276 times.
✓ Branch 2 taken 8777 times.
✓ Branch 3 taken 4295 times.
13108348 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return false;
2190 }
2191 276660338 c = MAPCOMBO(x,y);
2192
2/2
✓ Branch 0 taken 70747 times.
✓ Branch 1 taken 276589591 times.
276660338 if(ispitfall(c)) return true;
2193 276589591 return false;
2194 278127958 }
2195
2196 585542416 int32_t getpitfall(int32_t x, int32_t y) //Return the highest-layer active pit combo at the given position
2197 {
2198
2/2
✓ Branch 0 taken 9281019 times.
✓ Branch 1 taken 576261397 times.
585542416 if(int32_t c = MAPFFCOMBO(x,y))
2199 {
2200
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9281019 times.
9281019 return ispitfall(c) ? c : 0;
2201 }
2202 576261397 int32_t c = MAPCOMBOL(2,x,y);
2203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 576261397 times.
576261397 if(ispitfall(c)) return c;
2204
2205
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 43538912 times.
576261397 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2206 {
2207
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return 0;
2208 532722485 }
2209 else
2210 {
2211
3/4
✓ Branch 0 taken 35747 times.
✓ Branch 1 taken 43503165 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 35747 times.
43538912 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return 0;
2212 }
2213 576225650 c = MAPCOMBOL(1,x,y);
2214
2/2
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 576225372 times.
576225650 if(ispitfall(c)) return c;
2215
2216
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 43502887 times.
576225372 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2217 {
2218
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return 0;
2219 532722485 }
2220 else
2221 {
2222
4/4
✓ Branch 0 taken 144357 times.
✓ Branch 1 taken 43358530 times.
✓ Branch 2 taken 103729 times.
✓ Branch 3 taken 40628 times.
43502887 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return 0;
2223 }
2224 576121643 c = MAPCOMBO(x,y);
2225
2/2
✓ Branch 0 taken 176844 times.
✓ Branch 1 taken 575944799 times.
576121643 if(ispitfall(c)) return c;
2226 575944799 return 0;
2227 585542416 }
2228 51 optional<combined_handle_t> get_pitfall_handle(int32_t x, int32_t y) //Return the highest-layer active pit combo handle at the given position
2229 {
2230
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(int32_t c = MAPFFCOMBO(x,y))
2231 {
2232 return ispitfall(c) ? getFFCAt(x,y) : nullopt;
2233 }
2234 51 int32_t c = MAPCOMBOL(2,x,y);
2235
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 2);
2236
2237
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 45 times.
51 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2238 {
2239
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1))
2240 return nullopt;
2241 6 }
2242 else
2243 {
2244
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1))
2245 return nullopt;
2246 }
2247 51 c = MAPCOMBOL(1,x,y);
2248
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 1);
2249
2250
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 45 times.
51 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2251 {
2252
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0))
2253 return nullopt;
2254 6 }
2255 else
2256 {
2257
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0))
2258 return nullopt;
2259 }
2260 51 c = MAPCOMBO(x,y);
2261
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 0);
2262 return nullopt;
2263 51 }
2264 5426640 bool check_icy(newcombo const& cmb, int type)
2265 {
2266
2/2
✓ Branch 0 taken 5426475 times.
✓ Branch 1 taken 165 times.
5426640 if(cmb.type != cICY)
2267 5426475 return false;
2268
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 165 times.
165 switch(type)
2269 {
2270 case ICY_BLOCK:
2271 return cmb.usrflags&cflag1;
2272 case ICY_PLAYER:
2273 165 return cmb.usrflags&cflag2;
2274 }
2275 return false;
2276 5426640 }
2277 1811404 int get_icy(int x, int y, int type)
2278 {
2279 1811404 int32_t c = MAPCOMBOL(2,x,y);
2280
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1811404 times.
1811404 if(check_icy(combobuf[c], type)) return c;
2281
2282 1811404 int screen = get_screen_for_world_xy(x, y);
2283
2284 1811404 mapscr* scr = get_scr_layer_valid(screen, 2);
2285
2/2
✓ Branch 0 taken 430769 times.
✓ Branch 1 taken 1380635 times.
1811404 if (scr)
2286 {
2287
2/2
✓ Branch 0 taken 516 times.
✓ Branch 1 taken 1380119 times.
1380635 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2288 {
2289
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 516 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
516 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2290 516 }
2291 else
2292 {
2293
3/4
✓ Branch 0 taken 3048 times.
✓ Branch 1 taken 1377071 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3048 times.
1380119 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2294 }
2295 1377587 }
2296 1808356 c = MAPCOMBOL(1,x,y);
2297
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1808356 times.
1808356 if(check_icy(combobuf[c], type)) return c;
2298
2299 1808356 scr = get_scr_layer_valid(screen, 1);
2300
2/2
✓ Branch 0 taken 73612 times.
✓ Branch 1 taken 1734744 times.
1808356 if (scr)
2301 {
2302
2/2
✓ Branch 0 taken 1934 times.
✓ Branch 1 taken 1732810 times.
1734744 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2303 {
2304
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1934 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1934 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2305 1934 }
2306 else
2307 {
2308
3/4
✓ Branch 0 taken 1641 times.
✓ Branch 1 taken 1731169 times.
✓ Branch 2 taken 1641 times.
✗ Branch 3 not taken.
1732810 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2309 }
2310 1733103 }
2311 1806715 c = MAPCOMBO(x,y);
2312
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1806715 times.
1806715 if(check_icy(combobuf[c], type)) return c;
2313 1806715 return 0;
2314 1811404 }
2315
2316 13049036 static bool checkSV(int32_t x, int32_t y, int32_t flag)
2317 {
2318
8/8
✓ Branch 0 taken 13042238 times.
✓ Branch 1 taken 6798 times.
✓ Branch 2 taken 13033372 times.
✓ Branch 3 taken 8866 times.
✓ Branch 4 taken 13021740 times.
✓ Branch 5 taken 11632 times.
✓ Branch 6 taken 428468 times.
✓ Branch 7 taken 12593272 times.
13049036 if(x<0 || x>=world_w || y<0 || y>=world_h)
2319 455764 return false;
2320
2321 12593272 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
2322
2/4
✓ Branch 0 taken 12593272 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12593272 times.
12593272 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2323 return true;
2324
2325 12593272 change_rpos_handle_layer(rpos_handle, 1);
2326
2/2
✓ Branch 0 taken 7565562 times.
✓ Branch 1 taken 5027710 times.
12593272 if (rpos_handle.scr->is_valid())
2327
3/4
✓ Branch 0 taken 5027710 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3279 times.
✓ Branch 3 taken 5024431 times.
5027710 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2328 3279 return true;
2329
2330 12589993 change_rpos_handle_layer(rpos_handle, 2);
2331
2/2
✓ Branch 0 taken 10876856 times.
✓ Branch 1 taken 1713137 times.
12589993 if (rpos_handle.scr->is_valid())
2332
2/4
✓ Branch 0 taken 1713137 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1713137 times.
1713137 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2333 return true;
2334
2335 12589993 return false;
2336 13049036 }
2337
2338 6588680 bool isSVLadder(int32_t x, int32_t y)
2339 {
2340 6588680 return checkSV(x, y, mfSIDEVIEWLADDER);
2341 }
2342
2343 6460356 bool isSVPlatform(int32_t x, int32_t y)
2344 {
2345 6460356 return checkSV(x, y, mfSIDEVIEWPLATFORM);
2346 }
2347
2348 6460356 bool checkSVLadderPlatform(int32_t x, int32_t y)
2349 {
2350
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6460356 times.
✓ Branch 2 taken 6458559 times.
✓ Branch 3 taken 1797 times.
6460356 return isSVPlatform(x,y) || (isSVLadder(x,y) && !isSVLadder(x,y-16));
2351 }
2352
2353 1637 bool isstepable(int32_t combo) //can use ladder on it
2354 {
2355
2/2
✓ Branch 0 taken 1631 times.
✓ Branch 1 taken 6 times.
1637 if(combo_class_buf[combobuf[combo].type].ladder_pass) return true;
2356
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(combo_class_buf[combobuf[combo].type].pit)
2357 {
2358 if(combobuf[combo].usrflags&cflag4)
2359 {
2360 int32_t ldrid = current_item_id(itype_ladder);
2361 return (ldrid > -1 && itemsbuf[ldrid].flags & item_flag1);
2362 }
2363 }
2364 6 return false;
2365 1637 }
2366
2367 32780 bool isHSGrabbable(newcombo const& cmb)
2368 {
2369
2/2
✓ Branch 0 taken 373 times.
✓ Branch 1 taken 32407 times.
32780 if(cmb.type == cHSGRAB) return true;
2370 32407 return cmb.genflags & cflag1;
2371 32780 }
2372
2373 954 bool isSwitchHookable(newcombo const& cmb)
2374 {
2375
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 822 times.
954 if(cmb.type == cSWITCHHOOK) return true;
2376 822 return cmb.genflags & cflag2;
2377 954 }
2378
2379 61401 bool check_hshot(int32_t layer, int32_t x, int32_t y, bool switchhook, rpos_t *out_rpos, ffcdata **out_ffc)
2380 {
2381 61401 rpos_t cpos = rpos_t::None;
2382
2/2
✓ Branch 0 taken 64592 times.
✓ Branch 1 taken 125993 times.
61401 if(out_rpos)
2383 {
2384 125993 int32_t id = MAPCOMBO2(layer-1,x,y);
2385
2/2
✓ Branch 0 taken 28634 times.
✓ Branch 1 taken 97359 times.
125993 if(id > 0)
2386 {
2387 97359 newcombo const& cmb = combobuf[id];
2388
4/4
✓ Branch 0 taken 32738 times.
✓ Branch 1 taken 64621 times.
✓ Branch 2 taken 32296 times.
✓ Branch 3 taken 32325 times.
97359 cpos = (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb)) ? COMBOPOS_REGION(x,y) : rpos_t::None;
2389 32767 }
2390 61401 }
2391
2392 125993 ffcdata* ffc = nullptr;
2393
4/4
✓ Branch 0 taken 28389 times.
✓ Branch 1 taken 97604 times.
✓ Branch 2 taken 24996 times.
✓ Branch 3 taken 3393 times.
125993 if (out_ffc && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2394 {
2395 10359 for_some_ffcs([&](const ffc_handle_t& ffc_handle) {
2396
2/2
✓ Branch 0 taken 6853 times.
✓ Branch 1 taken 113 times.
6966 if (ffcIsAt(ffc_handle, x, y))
2397 {
2398 113 auto& cmb = ffc_handle.combo();
2399
4/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 71 times.
✓ Branch 2 taken 35 times.
✓ Branch 3 taken 36 times.
113 if (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb))
2400 {
2401 77 ffc = ffc_handle.ffc;
2402 77 return false;
2403 }
2404 36 }
2405 6889 return true;
2406 6896 });
2407 3393 }
2408
2409
4/4
✓ Branch 0 taken 61401 times.
✓ Branch 1 taken 64592 times.
✓ Branch 2 taken 442 times.
✓ Branch 3 taken 60959 times.
125993 if (out_rpos && cpos != rpos_t::None) *out_rpos = cpos;
2410
4/4
✓ Branch 0 taken 28389 times.
✓ Branch 1 taken 97604 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 28382 times.
125993 if (out_ffc && ffc) *out_ffc = ffc;
2411
2/2
✓ Branch 0 taken 65034 times.
✓ Branch 1 taken 60959 times.
125993 return (cpos != rpos_t::None || ffc);
2412 }
2413
2414 5195 bool ishookshottable(int32_t bx, int32_t by)
2415 {
2416
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5195 times.
5195 if(!_walkflag(bx,by,1))
2417 return true;
2418
2419
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5187 times.
5195 if (collide_object(bx, by, 1, 1))
2420 8 return false;
2421
2422 5187 bool ret = true;
2423
2/2
✓ Branch 0 taken 15561 times.
✓ Branch 1 taken 1900 times.
17461 for(int32_t i=2; i>=0; i--)
2424 {
2425 15561 int32_t c = MAPCOMBO2(i-1,bx,by);
2426 15561 int32_t t = combobuf[c].type;
2427
2428
6/6
✓ Branch 0 taken 5187 times.
✓ Branch 1 taken 10374 times.
✓ Branch 2 taken 3853 times.
✓ Branch 3 taken 1334 times.
✓ Branch 4 taken 1900 times.
✓ Branch 5 taken 1953 times.
15561 if(i == 0 && (t == cHOOKSHOTONLY || t == cLADDERHOOKSHOT)) return true;
2429
2430
3/4
✓ Branch 0 taken 11321 times.
✓ Branch 1 taken 953 times.
✓ Branch 2 taken 953 times.
✗ Branch 3 not taken.
13227 bool dried = (iswater_type(t) && DRIEDLAKE);
2431
2432 12274 int32_t b=1;
2433
2434
2/2
✓ Branch 0 taken 6109 times.
✓ Branch 1 taken 6165 times.
12274 if(bx&8) b<<=2;
2435
2436
2/2
✓ Branch 0 taken 3841 times.
✓ Branch 1 taken 8433 times.
12274 if(by&8) b<<=1;
2437
2438
7/8
✓ Branch 0 taken 2094 times.
✓ Branch 1 taken 10180 times.
✓ Branch 2 taken 2094 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1115 times.
✓ Branch 5 taken 979 times.
✓ Branch 6 taken 75 times.
✓ Branch 7 taken 904 times.
12274 if(combobuf[c].walk&b && !dried && !(combo_class_buf[t].ladder_pass && t!=cLADDERONLY) && t!=cHOOKSHOTONLY)
2439 904 ret = false;
2440 12274 }
2441
2442 1900 return ret;
2443 5195 }
2444
2445 10110 bool reveal_hidden_stairs(mapscr *s, int32_t screen, bool redraw)
2446 {
2447
4/4
✓ Branch 0 taken 9531 times.
✓ Branch 1 taken 579 times.
✓ Branch 2 taken 9531 times.
✓ Branch 3 taken 579 times.
10110 if((s->stairx || s->stairy) && s->secretcombo[sSTAIRS])
2448 {
2449 579 int pos = COMBOPOS(s->stairx,s->stairy);
2450 579 s->data[pos] = s->secretcombo[sSTAIRS];
2451 579 s->cset[pos] = s->secretcset[sSTAIRS];
2452 579 s->sflag[pos] = s->secretflag[sSTAIRS];
2453
2454
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 323 times.
579 if (redraw)
2455 {
2456 768 auto [x, y] = translate_screen_coordinates_to_world(screen, s->stairx, s->stairy);
2457 768 putcombo(scrollbuf,x,y,s->data[pos],s->cset[pos]);
2458 256 }
2459
2460 579 return true;
2461 }
2462
2463 9531 return false;
2464 10110 }
2465
2466 51768 screen_handles_t create_screen_handles_one(mapscr* base_scr)
2467 {
2468 DCHECK(base_scr->is_valid());
2469
2470 51768 screen_handles_t screen_handles{};
2471 51768 screen_handles[0] = {base_scr, base_scr, base_scr->screen, 0};
2472 51768 return screen_handles;
2473 }
2474
2475 56531351 screen_handles_t create_screen_handles(mapscr* base_scr)
2476 {
2477 DCHECK(get_scr(base_scr->screen) == base_scr);
2478 DCHECK(base_scr->is_valid());
2479
2480 56531351 int screen = base_scr->screen;
2481 screen_handles_t screen_handles;
2482 56531351 screen_handles[0] = {base_scr, base_scr, screen, 0};
2483
2/2
✓ Branch 0 taken 339188106 times.
✓ Branch 1 taken 56531351 times.
395719457 for (int i = 1; i <= 6; i++)
2484 339188106 screen_handles[i] = {base_scr, get_scr_layer_valid(screen, i), screen, i};
2485 56531351 return screen_handles;
2486 }
2487
2488 106202 bool remove_screenstatecombos2(const screen_handles_t& screen_handles, bool do_layers, int32_t what1, int32_t what2)
2489 {
2490 106202 mapscr* scr = screen_handles[0].scr;
2491 106202 bool didit=false;
2492
2493
2/2
✓ Branch 0 taken 106202 times.
✓ Branch 1 taken 18691552 times.
18797754 for(int32_t i=0; i<176; i++)
2494 {
2495 18691552 newcombo const& cmb = combobuf[scr->data[i]];
2496
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 18691226 times.
18691552 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2497
4/4
✓ Branch 0 taken 18689693 times.
✓ Branch 1 taken 1533 times.
✓ Branch 2 taken 1102 times.
✓ Branch 3 taken 18688591 times.
18691226 if((cmb.type == what1) || (cmb.type== what2))
2498 {
2499 2635 scr->data[i]++;
2500 2635 didit=true;
2501 2635 }
2502 18691226 }
2503
2504
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 106110 times.
106202 if (do_layers)
2505 {
2506
2/2
✓ Branch 0 taken 636660 times.
✓ Branch 1 taken 106110 times.
742770 for(int32_t j=1; j<=6; j++)
2507 {
2508 636660 mapscr* layer_scr = screen_handles[j].scr;
2509
2/2
✓ Branch 0 taken 173044 times.
✓ Branch 1 taken 463616 times.
636660 if (!layer_scr) continue;
2510
2511
2/2
✓ Branch 0 taken 30455744 times.
✓ Branch 1 taken 173044 times.
30628788 for(int32_t i=0; i<176; i++)
2512 {
2513 30455744 newcombo const& cmb = combobuf[layer_scr->data[i]];
2514
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30455744 times.
30455744 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2515
4/4
✓ Branch 0 taken 30455661 times.
✓ Branch 1 taken 83 times.
✓ Branch 2 taken 265 times.
✓ Branch 3 taken 30455396 times.
30455744 if((cmb.type== what1) || (cmb.type== what2))
2516 {
2517 348 layer_scr->data[i]++;
2518 348 didit=true;
2519 348 }
2520 30455744 }
2521 173044 }
2522 106110 }
2523
2524 // 'do_layers' also means that this is called on an active temp screen, so update its ffcs.
2525
3/4
✓ Branch 0 taken 20406 times.
✓ Branch 1 taken 85796 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 20406 times.
106202 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && do_layers)
2526 {
2527 20406 word c = scr->numFFC();
2528
2/2
✓ Branch 0 taken 73350 times.
✓ Branch 1 taken 20406 times.
93756 for(word i=0; i<c; i++)
2529 {
2530 73350 ffcdata* ffc = &scr->ffcs[i];
2531 73350 newcombo const& cmb = combobuf[ffc->data];
2532
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73350 times.
73350 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2533
2/4
✓ Branch 0 taken 73350 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 73350 times.
73350 if((cmb.type== what1) || (cmb.type== what2))
2534 {
2535 zc_ffc_modify(*ffc, 1);
2536 didit=true;
2537 }
2538 73350 }
2539 20406 }
2540
2541 106202 return didit;
2542 }
2543
2544 14 bool remove_xstatecombos(const screen_handles_t& screen_handles, byte xflag, bool triggers)
2545 {
2546 14 int screen = screen_handles[0].scr->screen;
2547
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2548 14 return remove_xstatecombos_mi(screen_handles, mi, xflag, triggers);
2549 }
2550 471496206 bool remove_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, byte xflag, bool triggers)
2551 {
2552 471496206 bool didit=false;
2553
2/2
✓ Branch 0 taken 471467348 times.
✓ Branch 1 taken 28858 times.
471496206 if(!getxmapflag_mi(mi, 1<<xflag)) return false;
2554
2555 28858 mapscr* s = screen_handles[0].scr;
2556 28858 int screen = s->screen;
2557 28858 bool is_active_screen = is_in_current_region(s);
2558
2559 24248394 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2560
4/4
✓ Branch 0 taken 24207920 times.
✓ Branch 1 taken 11616 times.
✓ Branch 2 taken 24206112 times.
✓ Branch 3 taken 1808 times.
24219536 if(triggers && force_ex_trigger_any(rpos_handle, xflag))
2561 1808 didit = true;
2562
2/2
✓ Branch 0 taken 63627 times.
✓ Branch 1 taken 24154101 times.
24217728 else switch (rpos_handle.ctype())
2563 {
2564 case cLOCKBLOCK: case cLOCKBLOCK2:
2565 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2566 case cCHEST: case cCHEST2:
2567 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2568 case cBOSSCHEST: case cBOSSCHEST2:
2569 {
2570 63627 auto& cmb = rpos_handle.combo();
2571
2/2
✓ Branch 0 taken 62059 times.
✓ Branch 1 taken 1568 times.
63627 if(!(cmb.usrflags&cflag16)) return; //custom state instead of normal state
2572
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 62030 times.
62059 if(cmb.attribytes[5] == xflag)
2573 {
2574 29 rpos_handle.increment_data();
2575 29 didit=true;
2576 29 }
2577 62059 break;
2578 }
2579 }
2580 24219536 });
2581
2582
4/4
✓ Branch 0 taken 28817 times.
✓ Branch 1 taken 41 times.
✓ Branch 2 taken 19197 times.
✓ Branch 3 taken 9620 times.
28858 if (is_active_screen && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2583 {
2584 19197 word c = s->numFFC();
2585 19197 int screen_index_offset = get_region_screen_offset(screen);
2586
2/2
✓ Branch 0 taken 36840 times.
✓ Branch 1 taken 19197 times.
56037 for (uint8_t i = 0; i < c; i++)
2587 {
2588 36840 auto ffc_handle = *s->getFFCHandle(i, screen_index_offset);
2589 36840 auto& cmb = ffc_handle.combo();
2590
3/4
✓ Branch 0 taken 36840 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36824 times.
✓ Branch 3 taken 16 times.
36840 if(triggers && force_ex_trigger_ffc_any(ffc_handle, xflag))
2591 16 didit = true;
2592
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36824 times.
36824 else switch(cmb.type)
2593 {
2594 case cLOCKBLOCK: case cLOCKBLOCK2:
2595 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2596 case cCHEST: case cCHEST2:
2597 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2598 case cBOSSCHEST: case cBOSSCHEST2:
2599 {
2600 if(!(cmb.usrflags&cflag16)) continue; //custom state instead of normal state
2601 if(cmb.attribytes[5] == xflag)
2602 {
2603 zc_ffc_modify(*ffc_handle.ffc, 1);
2604 didit=true;
2605 }
2606 break;
2607 }
2608 }
2609 36840 }
2610 19197 }
2611
2612 28858 return didit;
2613 471496206 }
2614
2615 14682265 void clear_xstatecombos(const screen_handles_t& screen_handles, bool triggers)
2616 {
2617 14682265 int screen = screen_handles[0].screen;
2618
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14294432 times.
14682265 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2619 14682265 clear_xstatecombos_mi(screen_handles, mi, triggers);
2620 14682265 }
2621
2622 14734256 void clear_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2623 {
2624
2/2
✓ Branch 0 taken 471496192 times.
✓ Branch 1 taken 14734256 times.
486230448 for (int q = 0; q < 32; ++q)
2625 {
2626 471496192 remove_xstatecombos_mi(screen_handles, mi, q, triggers);
2627 471496192 }
2628 14734256 }
2629
2630 bool remove_xdoors(const screen_handles_t& screen_handles, uint dir, uint ind, bool triggers)
2631 {
2632 int screen = screen_handles[0].screen;
2633 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2634 return remove_xdoors_mi(screen_handles, mi, dir, ind, triggers);
2635 }
2636 471496192 bool remove_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, uint dir, uint ind, bool triggers)
2637 {
2638 471496192 bool didit=false;
2639
2/2
✓ Branch 0 taken 471494879 times.
✓ Branch 1 taken 1313 times.
471496192 if (!getxdoor_mi(mi, dir, ind)) return false;
2640
2641 1313 mapscr* scr = screen_handles[0].scr;
2642 1313 int screen = scr->screen;
2643 1313 bool is_active_screen = is_in_current_region(scr);
2644
2645 925665 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2646
3/4
✓ Branch 0 taken 924352 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 924341 times.
924352 if (triggers && force_ex_door_trigger_any(rpos_handle, dir, ind))
2647 11 didit = true;
2648 else; //future door combo types?
2649 924352 });
2650
2651
2/4
✓ Branch 0 taken 1313 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1313 times.
✗ Branch 3 not taken.
1313 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && is_active_screen)
2652 {
2653 1313 word c = scr->numFFC();
2654 1313 int screen_index_offset = get_region_screen_offset(screen);
2655
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1313 times.
1313 for (uint8_t i = 0; i < c; i++)
2656 {
2657 auto ffc_handle = *scr->getFFCHandle(i, screen_index_offset);
2658 if (triggers && force_ex_door_trigger_ffc_any(ffc_handle, dir, ind))
2659 didit = true;
2660 else; //future door combo types?
2661 }
2662 1313 }
2663
2664 1313 return didit;
2665 471496192 }
2666
2667 14682265 void clear_xdoors(const screen_handles_t& screen_handles, bool triggers)
2668 {
2669 14682265 int screen = screen_handles[0].screen;
2670
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14294432 times.
14682265 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2671 14682265 return clear_xdoors_mi(screen_handles, mi, triggers);
2672 }
2673
2674 14734256 void clear_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2675 {
2676
2/2
✓ Branch 0 taken 58937024 times.
✓ Branch 1 taken 14734256 times.
73671280 for (int dir = 0; dir < 4; ++dir)
2677
2/2
✓ Branch 0 taken 471496192 times.
✓ Branch 1 taken 58937024 times.
530433216 for (int q = 0; q < 8; ++q)
2678 530433216 remove_xdoors_mi(screen_handles, mi, dir, q, triggers);
2679 14734256 }
2680
2681 763 bool remove_lockblocks(const screen_handles_t& screen_handles)
2682 {
2683 763 return remove_screenstatecombos2(screen_handles, true, cLOCKBLOCK, cLOCKBLOCK2);
2684 }
2685
2686 98 bool remove_bosslockblocks(const screen_handles_t& screen_handles)
2687 {
2688 98 return remove_screenstatecombos2(screen_handles, true, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
2689 }
2690
2691 76553 bool remove_chests(const screen_handles_t& screen_handles)
2692 {
2693 76553 return remove_screenstatecombos2(screen_handles, true, cCHEST, cCHEST2);
2694 }
2695
2696 2484 bool remove_lockedchests(const screen_handles_t& screen_handles)
2697 {
2698 2484 return remove_screenstatecombos2(screen_handles, true, cLOCKEDCHEST, cLOCKEDCHEST2);
2699 }
2700
2701 26212 bool remove_bosschests(const screen_handles_t& screen_handles)
2702 {
2703 26212 return remove_screenstatecombos2(screen_handles, true, cBOSSCHEST, cBOSSCHEST2);
2704 }
2705
2706 1384361 void delete_fireball_shooter(const rpos_handle_t& rpos_handle)
2707 {
2708 1384361 int32_t ct=rpos_handle.ctype();
2709
2710
6/6
✓ Branch 0 taken 1383741 times.
✓ Branch 1 taken 620 times.
✓ Branch 2 taken 1383489 times.
✓ Branch 3 taken 252 times.
✓ Branch 4 taken 1383381 times.
✓ Branch 5 taken 108 times.
1384361 if(ct!=cL_STATUE && ct!=cR_STATUE && ct!=cC_STATUE)
2711 1383381 return;
2712
2713 2465 auto [cx, cy] = rpos_handle.xy();
2714
3/4
✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 620 times.
✓ Branch 3 taken 108 times.
980 switch(ct)
2715 {
2716 case cL_STATUE:
2717 620 cx += 4;
2718 620 cy += 7;
2719 620 break;
2720
2721 case cR_STATUE:
2722 252 cx -= 8;
2723 252 cy -= 1;
2724 252 break;
2725
2726 case cC_STATUE:
2727 108 break;
2728 }
2729
2730
2/2
✓ Branch 0 taken 980 times.
✓ Branch 1 taken 1485 times.
2465 for(int32_t j=0; j<guys.Count(); j++)
2731 {
2732 // Finds the smallest enemy ID
2733
9/10
✓ Branch 0 taken 399 times.
✓ Branch 1 taken 1086 times.
✓ Branch 2 taken 399 times.
✓ Branch 3 taken 1086 times.
✓ Branch 4 taken 346 times.
✓ Branch 5 taken 53 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 53 times.
✓ Branch 8 taken 346 times.
✗ Branch 9 not taken.
2970 if((int32_t(guys.spr(j)->x)==cx)&&(int32_t(guys.spr(j)->y)==cy)&&(guysbuf[(guys.spr(j)->id)&0xFFF].flags & guy_fire))
2734 {
2735 346 guys.del(j);
2736 346 }
2737 1485 }
2738 1384361 }
2739
2740 15 static int32_t findtrigger(int32_t screen)
2741 {
2742 15 int32_t checkflag=0;
2743 15 int32_t ret = 0;
2744
2745 mapscr* screens[7];
2746
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 15 times.
120 for (int32_t j = 0; j <= 6; j++)
2747 {
2748 105 screens[j] = get_scr_layer_valid(screen, j);
2749 105 }
2750
2751 15 bool sflag = false;
2752
2/2
✓ Branch 0 taken 2640 times.
✓ Branch 1 taken 15 times.
2655 for(word j=0; j<176; j++)
2753 {
2754
2/2
✓ Branch 0 taken 26752 times.
✓ Branch 1 taken 2640 times.
29392 for(int32_t layer = -1; layer < 6; ++layer)
2755 {
2756 26752 mapscr* scr = screens[layer+1];
2757
2/2
✓ Branch 0 taken 16544 times.
✓ Branch 1 taken 10208 times.
26752 if (!scr) continue;
2758
2759
2/2
✓ Branch 0 taken 8272 times.
✓ Branch 1 taken 8272 times.
16544 if(sflag)
2760 8272 checkflag = scr->sflag[j];
2761 else
2762 8272 checkflag = combobuf[scr->data[j]].flag;
2763 16544 sflag = !sflag;
2764
2/2
✓ Branch 0 taken 8272 times.
✓ Branch 1 taken 8272 times.
16544 if (sflag) --layer;
2765
2766
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 16534 times.
16544 switch(checkflag)
2767 {
2768 case mfANYFIRE:
2769 case mfSTRONGFIRE:
2770 case mfMAGICFIRE:
2771 case mfDIVINEFIRE:
2772 case mfARROW:
2773 case mfSARROW:
2774 case mfGARROW:
2775 case mfSBOMB:
2776 case mfBOMB:
2777 case mfBRANG:
2778 case mfMBRANG:
2779 case mfFBRANG:
2780 case mfWANDMAGIC:
2781 case mfREFMAGIC:
2782 case mfREFFIREBALL:
2783 case mfSWORD:
2784 case mfWSWORD:
2785 case mfMSWORD:
2786 case mfXSWORD:
2787 case mfSWORDBEAM:
2788 case mfWSWORDBEAM:
2789 case mfMSWORDBEAM:
2790 case mfXSWORDBEAM:
2791 case mfHOOKSHOT:
2792 case mfWAND:
2793 case mfHAMMER:
2794 case mfSTRIKE:
2795 10 ret += 1;
2796 10 break;
2797 }
2798 16544 }
2799 2640 }
2800
2801 15 return ret;
2802 }
2803
2804 11738 static void log_trigger_secret_reason(TriggerSource source)
2805 {
2806
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11299 times.
11738 if (source == TriggerSource::Singular)
2807 {
2808 439 Z_eventlog("Restricted Screen Secrets triggered\n");
2809 439 }
2810 else
2811 {
2812 11299 const char* source_str = "";
2813
7/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 7178 times.
✓ Branch 3 taken 856 times.
✓ Branch 4 taken 2733 times.
✓ Branch 5 taken 475 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 52 times.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
11299 switch (source)
2814 {
2815 case TriggerSource::Singular: break;
2816 7178 case TriggerSource::Unspecified: source_str = "unspecified means"; break;
2817 856 case TriggerSource::EnemiesScreenFlag: source_str = "the 'Enemies->Secret' screen flag"; break;
2818 2733 case TriggerSource::SecretsScreenState: source_str = "the 'Secrets' screen state"; break;
2819 475 case TriggerSource::Script: source_str = "a script"; break;
2820 1 case TriggerSource::ItemsSecret: source_str = "Items->Secrets"; break;
2821 52 case TriggerSource::GenericCombo: source_str = "Generic Combo"; break;
2822 4 case TriggerSource::LightTrigger: source_str = "Light Triggers"; break;
2823 case TriggerSource::SCC: source_str = "SCC"; break;
2824 case TriggerSource::CheatTemp: source_str = "Cheat (Temp)"; break;
2825 case TriggerSource::CheatPerm: source_str = "Cheat (Perm)"; break;
2826 }
2827 11299 Z_eventlog("Screen Secrets triggered by %s\n", source_str);
2828 }
2829 11738 }
2830
2831 // single:
2832 // >-1 : the singular triggering combo
2833 // -1: triggered by some other cause
2834 11530 void trigger_secrets_for_screen(TriggerSource source, mapscr* scr, bool high16only, int32_t single)
2835 {
2836 11530 log_trigger_secret_reason(source);
2837
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11091 times.
11530 if (single < 0)
2838 11091 get_screen_state(scr->screen).triggered_secrets = true;
2839
2840 11530 bool do_replay_comment = true;
2841 11530 bool from_active_screen = true;
2842 11530 trigger_secrets_for_screen_internal(create_screen_handles(scr), from_active_screen, high16only, single, do_replay_comment);
2843
2844 // Respect secret state carryovers for active screens.
2845
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11091 times.
11530 if (single >= 0) return;
2846
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 11068 times.
11091 if(scr->nocarry&mSECRET) return;
2847 11068 int cmap = scr->map;
2848 11068 int cscr = scr->screen;
2849 11068 int nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
2850 11068 int nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
2851
2852 11068 std::vector<int32_t> done;
2853
2/2
✓ Branch 0 taken 10896 times.
✓ Branch 1 taken 172 times.
11068 bool looped = (nmap==cmap+1 && nscr==cscr);
2854
2855
6/6
✓ Branch 0 taken 484 times.
✓ Branch 1 taken 11001 times.
✓ Branch 2 taken 67 times.
✓ Branch 3 taken 417 times.
✓ Branch 4 taken 417 times.
✓ Branch 5 taken 11068 times.
11485 while((nmap!=0) && !looped && !(nscr>=128))
2856 {
2857
7/8
✓ Branch 0 taken 317 times.
✓ Branch 1 taken 100 times.
✓ Branch 2 taken 74 times.
✓ Branch 3 taken 243 times.
✓ Branch 4 taken 74 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 70 times.
417 if (nmap - 1 == cur_map && is_in_current_region(nscr) && !get_screen_state(nscr).triggered_secrets)
2858 {
2859
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
2860
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 trigger_secrets_for_screen_internal(create_screen_handles(get_scr(nscr)), from_active_screen, high16only, single, do_replay_comment);
2861
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 get_screen_state(nscr).triggered_secrets = true;
2862 4 }
2863
2864 417 cmap=nmap;
2865 417 cscr=nscr;
2866 417 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
2867 417 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
2868
2869
2/2
✓ Branch 0 taken 386 times.
✓ Branch 1 taken 417 times.
803 for(auto it = done.begin(); it != done.end(); it++)
2870 {
2871
2/2
✓ Branch 0 taken 319 times.
✓ Branch 1 taken 67 times.
386 if(*it == ((nmap-1)<<7)+nscr)
2872 67 looped = true;
2873 386 }
2874
2875
1/2
✓ Branch 0 taken 417 times.
✗ Branch 1 not taken.
417 done.push_back(((nmap-1)<<7)+nscr);
2876 }
2877 11530 }
2878
2879 2437 void trigger_secrets_for_screen(TriggerSource source, int32_t screen, bool high16only, int32_t single)
2880 {
2881 2437 trigger_secrets_for_screen(source, get_scr(screen), high16only, single);
2882 2437 }
2883
2884 18007 void trigger_secrets_for_screen_internal(const screen_handles_t& screen_handles, bool from_active_screen, bool high16only, int32_t single, bool do_replay_comment)
2885 {
2886 18007 mapscr* scr = screen_handles[0].scr;
2887 18007 int screen = scr->screen;
2888
2889 // TODO(replays): No real reason for "do_replay_comment" to exist - I just did not want to update many replays when fixing
2890 // slopes in sideview mode (which required loading nearby screens in loadscr).
2891 // TODO(replays): This should just use `screen`.
2892
3/4
✓ Branch 0 taken 18007 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 539 times.
✓ Branch 3 taken 17468 times.
18007 if (replay_is_active() && do_replay_comment)
2893
4/6
✓ Branch 0 taken 11534 times.
✓ Branch 1 taken 5934 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11534 times.
✓ Branch 4 taken 17468 times.
✗ Branch 5 not taken.
17468 replay_step_comment(fmt::format("trigger secrets scr={}", from_active_screen && scr != special_warp_return_scr ? screen : cur_screen));
2894
2895
2/2
✓ Branch 0 taken 6473 times.
✓ Branch 1 taken 11534 times.
18007 if (from_active_screen)
2896 {
2897 5442998 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
2898
2/4
✓ Branch 0 taken 5429776 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1688 times.
✗ Branch 3 not taken.
5661701 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
2899 230237 return trig.trigger_flags.get(TRIGFLAG_SECRETSTR);
2900 }, ctrigSECRETS);
2901 5431464 });
2902 11534 }
2903
2904 18007 int32_t ft=0; //Flag trigger?
2905 18007 int32_t msflag=0; // Misc. secret flag
2906
2907
2/2
✓ Branch 0 taken 3169232 times.
✓ Branch 1 taken 18007 times.
3187239 for(int32_t i=0; i<176; i++) //Do the 'trigger flags' (non 16-31)
2908 {
2909
4/4
✓ Branch 0 taken 77264 times.
✓ Branch 1 taken 3091968 times.
✓ Branch 2 taken 439 times.
✓ Branch 3 taken 76825 times.
3169232 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2910
2911 // Remember the misc. secret flag; if triggered, use this instead
2912
4/4
✓ Branch 0 taken 114511 times.
✓ Branch 1 taken 2977896 times.
✓ Branch 2 taken 49462 times.
✓ Branch 3 taken 65049 times.
3092407 if(scr->sflag[i]>=mfSECRETS01 && scr->sflag[i]<=mfSECRETS16)
2913 65049 msflag=sSECRET01+(scr->sflag[i]-mfSECRETS01);
2914
4/4
✓ Branch 0 taken 47230 times.
✓ Branch 1 taken 2980128 times.
✓ Branch 2 taken 46999 times.
✓ Branch 3 taken 231 times.
3027358 else if(combobuf[scr->data[i]].flag>=mfSECRETS01 && combobuf[scr->data[i]].flag<=mfSECRETS16)
2915 231 msflag=sSECRET01+(combobuf[scr->data[i]].flag-mfSECRETS01);
2916 else
2917 3027127 msflag=0;
2918
2919
4/4
✓ Branch 0 taken 921256 times.
✓ Branch 1 taken 2171151 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 921184 times.
3092407 if(!high16only || single>=0)
2920 {
2921 2171223 int32_t newflag = -1;
2922
2923
2/2
✓ Branch 0 taken 4342446 times.
✓ Branch 1 taken 2171223 times.
6513669 for(int32_t iter=0; iter<2; ++iter)
2924 {
2925 4342446 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
2926
2927
2/2
✓ Branch 0 taken 2171223 times.
✓ Branch 1 taken 2171223 times.
4342446 if(iter==1) checkflag=scr->sflag[i]; //Placed
2928
2929 4342446 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2930
2/2
✓ Branch 0 taken 4330212 times.
✓ Branch 1 taken 12234 times.
4342446 if (ft != -1) //Change the combos for the secret
2931 {
2932 // Use misc. secret flag instead if one is present
2933
2/2
✓ Branch 0 taken 12202 times.
✓ Branch 1 taken 32 times.
12234 if(msflag!=0)
2934 32 ft=msflag;
2935
2936 12234 rpos_handle_t rpos_handle;
2937
2/2
✓ Branch 0 taken 6367 times.
✓ Branch 1 taken 5867 times.
12234 if (from_active_screen)
2938 {
2939 5867 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
2940 5867 screen_combo_modify_preroutine(rpos_handle);
2941 5867 }
2942
2943
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12234 times.
12234 if(ft==sSECNEXT)
2944 {
2945 scr->data[i]++;
2946 }
2947 else
2948 {
2949 12234 scr->data[i] = scr->secretcombo[ft];
2950 12234 scr->cset[i] = scr->secretcset[ft];
2951 }
2952 12234 newflag = scr->secretflag[ft];
2953
2954
2/2
✓ Branch 0 taken 6367 times.
✓ Branch 1 taken 5867 times.
12234 if (from_active_screen)
2955 5867 screen_combo_modify_postroutine(rpos_handle);
2956 12234 }
2957 4342446 }
2958
2959
2/2
✓ Branch 0 taken 2158995 times.
✓ Branch 1 taken 12228 times.
2171223 if(newflag >-1) scr->sflag[i] = newflag; //Tiered secret
2960
2961
2/2
✓ Branch 0 taken 13027338 times.
✓ Branch 1 taken 2171223 times.
15198561 for(int32_t j=1; j<=6; j++) //Layers
2962 {
2963 13027338 mapscr* layer_scr = screen_handles[j].scr;
2964
2/2
✓ Branch 0 taken 3185797 times.
✓ Branch 1 taken 9841541 times.
13027338 if (!layer_scr) continue;
2965
2966
3/4
✓ Branch 0 taken 725 times.
✓ Branch 1 taken 3185072 times.
✓ Branch 2 taken 725 times.
✗ Branch 3 not taken.
3185797 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2967
2968 3185797 int32_t newflag2 = -1;
2969
2970 // Remember the misc. secret flag; if triggered, use this instead
2971
4/4
✓ Branch 0 taken 14182 times.
✓ Branch 1 taken 3171615 times.
✓ Branch 2 taken 4773 times.
✓ Branch 3 taken 9409 times.
3185797 if(layer_scr->sflag[i]>=mfSECRETS01 && layer_scr->sflag[i]<=mfSECRETS16)
2972 9409 msflag=sSECRET01+(layer_scr->sflag[i]-mfSECRETS01);
2973
4/4
✓ Branch 0 taken 126931 times.
✓ Branch 1 taken 3049457 times.
✓ Branch 2 taken 126560 times.
✓ Branch 3 taken 371 times.
3176388 else if(combobuf[layer_scr->data[i]].flag>=mfSECRETS01 && combobuf[layer_scr->data[i]].flag<=mfSECRETS16)
2974 371 msflag=sSECRET01+(combobuf[layer_scr->data[i]].flag-mfSECRETS01);
2975 else
2976 3176017 msflag=0;
2977
2978
2/2
✓ Branch 0 taken 6371594 times.
✓ Branch 1 taken 3185797 times.
9557391 for(int32_t iter=0; iter<2; ++iter)
2979 {
2980 6371594 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
2981
2/2
✓ Branch 0 taken 3185797 times.
✓ Branch 1 taken 3185797 times.
6371594 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
2982
2983 6371594 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2984
2/2
✓ Branch 0 taken 6371116 times.
✓ Branch 1 taken 478 times.
6371594 if (ft != -1) //Change the combos for the secret
2985 {
2986 // Use misc. secret flag instead if one is present
2987
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 2 times.
478 if(msflag!=0)
2988 2 ft=msflag;
2989
2990
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 478 times.
478 if(ft==sSECNEXT)
2991 {
2992 layer_scr->data[i]++;
2993 }
2994 else
2995 {
2996 478 layer_scr->data[i] = layer_scr->secretcombo[ft];
2997 478 layer_scr->cset[i] = layer_scr->secretcset[ft];
2998 }
2999 478 newflag2 = layer_scr->secretflag[ft];
3000 478 int32_t c=layer_scr->data[i];
3001 478 int32_t cs=layer_scr->cset[i];
3002
3003
3/4
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 406 times.
✗ Branch 3 not taken.
478 if (from_active_screen && combobuf[c].type==cSPINTILE1) //Surely this means we can have spin tiles on layers 3+? Isn't that bad? ~Joe123
3004 {
3005 auto [offx, offy] = translate_screen_coordinates_to_world(screen, COMBOX(i), COMBOY(i));
3006 addenemy(screen,offx,offy,(cs<<12)+eSPINTILE1,combobuf[c].o_tile+zc_max(1,combobuf[c].frames));
3007 }
3008 478 }
3009 6371594 }
3010
3011
2/2
✓ Branch 0 taken 478 times.
✓ Branch 1 taken 3185319 times.
3185797 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered secret
3012 3185797 }
3013 2171223 }
3014 3092407 }
3015
3016 18007 word c = scr->numFFC();
3017
2/2
✓ Branch 0 taken 506903 times.
✓ Branch 1 taken 18007 times.
524910 for(word i=0; i<c; i++) //FFC 'trigger flags'
3018 {
3019
3/4
✓ Branch 0 taken 492983 times.
✓ Branch 1 taken 13920 times.
✓ Branch 2 taken 13920 times.
✗ Branch 3 not taken.
506903 if(single>=0) if(i+176!=single) continue;
3020
3021
3/4
✓ Branch 0 taken 166605 times.
✓ Branch 1 taken 326378 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 166605 times.
492983 if((!high16only)||(single>=0))
3022 {
3023 //for (int32_t iter=0; iter<1; ++iter) // Only one kind of FFC flag now.
3024 {
3025 326378 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3026 //No placed flags yet
3027
3028 326378 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
3029
2/2
✓ Branch 0 taken 326347 times.
✓ Branch 1 taken 31 times.
326378 if (ft != -1) //Change the ffc's combo
3030 {
3031
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if(ft==sSECNEXT)
3032 {
3033 zc_ffc_modify(scr->ffcs[i], 1);
3034 }
3035 else
3036 {
3037 31 zc_ffc_set(scr->ffcs[i], scr->secretcombo[ft]);
3038 31 scr->ffcs[i].cset = scr->secretcset[ft];
3039 }
3040 31 }
3041 }
3042 326378 }
3043 492983 }
3044
3045
2/2
✓ Branch 0 taken 15610 times.
✓ Branch 1 taken 2397 times.
18007 if(checktrigger) //Hit all triggers->16-31
3046 {
3047 2397 checktrigger=false;
3048
3049
2/2
✓ Branch 0 taken 2388 times.
✓ Branch 1 taken 9 times.
2397 if(scr->flags6&fTRIGGERF1631)
3050 {
3051 9 int32_t tr = findtrigger(screen); //Normal flags
3052
3053
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
9 if(tr)
3054 {
3055 5 Z_eventlog("Hit All Triggers->16-31 not fulfilled (%d trigger flag%s remain).\n", tr, tr>1?"s":"");
3056 5 goto endhe;
3057 }
3058 4 }
3059 2392 }
3060
3061
2/2
✓ Branch 0 taken 3168352 times.
✓ Branch 1 taken 18002 times.
3186354 for(int32_t i=0; i<176; i++) // Do the 16-31 secrets
3062 {
3063 //If it's an enemies->secret screen, only do the high 16 if told to
3064 //That way you can have secret and burn/bomb entrance separately
3065 3168352 bool old_enem_secret = get_qr(qr_ENEMIES_SECRET_ONLY_16_31);
3066
6/6
✓ Branch 0 taken 2780624 times.
✓ Branch 1 taken 387728 times.
✓ Branch 2 taken 85184 times.
✓ Branch 3 taken 3083168 times.
✓ Branch 4 taken 19536 times.
✓ Branch 5 taken 65648 times.
3168352 if(((!(old_enem_secret && (scr->flags2&fCLEARSECRET)) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM))
3067 {
3068 3102704 int32_t newflag = -1;
3069
3070
2/2
✓ Branch 0 taken 6205408 times.
✓ Branch 1 taken 3102704 times.
9308112 for(int32_t iter=0; iter<2; ++iter)
3071 {
3072 6205408 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
3073
3074
2/2
✓ Branch 0 taken 3102704 times.
✓ Branch 1 taken 3102704 times.
6205408 if(iter==1) checkflag=scr->sflag[i]; //Placed
3075
3076
4/4
✓ Branch 0 taken 161185 times.
✓ Branch 1 taken 6044223 times.
✓ Branch 2 taken 94853 times.
✓ Branch 3 taken 66332 times.
6205408 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3077 {
3078 66332 rpos_handle_t rpos_handle;
3079
2/2
✓ Branch 0 taken 9952 times.
✓ Branch 1 taken 56380 times.
66332 if (from_active_screen)
3080 {
3081 56380 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
3082 56380 screen_combo_modify_preroutine(rpos_handle);
3083 56380 }
3084
3085 66332 scr->data[i] = scr->secretcombo[checkflag-16+4];
3086 66332 scr->cset[i] = scr->secretcset[checkflag-16+4];
3087 66332 newflag = scr->secretflag[checkflag-16+4];
3088
3089
2/2
✓ Branch 0 taken 9952 times.
✓ Branch 1 taken 56380 times.
66332 if (from_active_screen)
3090 56380 screen_combo_modify_postroutine(rpos_handle);
3091 66332 }
3092 6205408 }
3093
3094
2/2
✓ Branch 0 taken 3036396 times.
✓ Branch 1 taken 66308 times.
3102704 if(newflag >-1) scr->sflag[i] = newflag; //Tiered flag
3095
3096
2/2
✓ Branch 0 taken 18616224 times.
✓ Branch 1 taken 3102704 times.
21718928 for(int32_t j=1; j<=6; j++) //Layers
3097 {
3098 18616224 mapscr* layer_scr = screen_handles[j].scr;
3099
2/2
✓ Branch 0 taken 4866752 times.
✓ Branch 1 taken 13749472 times.
18616224 if (!layer_scr) continue;
3100
3101 4866752 int32_t newflag2 = -1;
3102
3103
2/2
✓ Branch 0 taken 9733504 times.
✓ Branch 1 taken 4866752 times.
14600256 for(int32_t iter=0; iter<2; ++iter)
3104 {
3105 9733504 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
3106
3107
2/2
✓ Branch 0 taken 4866752 times.
✓ Branch 1 taken 4866752 times.
9733504 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
3108
3109
4/4
✓ Branch 0 taken 151246 times.
✓ Branch 1 taken 9582258 times.
✓ Branch 2 taken 131622 times.
✓ Branch 3 taken 19624 times.
9733504 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3110 {
3111 19624 layer_scr->data[i] = layer_scr->secretcombo[checkflag-16+4];
3112 19624 layer_scr->cset[i] = layer_scr->secretcset[checkflag-16+4];
3113 19624 newflag2 = layer_scr->secretflag[checkflag-16+4];
3114 19624 }
3115 9733504 }
3116
3117
2/2
✓ Branch 0 taken 4847128 times.
✓ Branch 1 taken 19624 times.
4866752 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered flag
3118 4866752 }
3119 3102704 }
3120 3168352 }
3121
3122
2/2
✓ Branch 0 taken 506743 times.
✓ Branch 1 taken 18002 times.
524745 for(word i=0; i<c; i++) // FFCs
3123 {
3124
6/6
✓ Branch 0 taken 466852 times.
✓ Branch 1 taken 39891 times.
✓ Branch 2 taken 15367 times.
✓ Branch 3 taken 491376 times.
✓ Branch 4 taken 3530 times.
✓ Branch 5 taken 11837 times.
506743 if((!(scr->flags2&fCLEARSECRET) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM)
3125 {
3126 494906 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3127
3128 //No placed flags yet
3129
4/4
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 494838 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 12 times.
494906 if((checkflag > 15)&&(checkflag < 32)) //If we find a flag, change the combo
3130 {
3131
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 if (from_active_screen)
3132 9 zc_ffc_set(scr->ffcs[i], scr->secretcombo[checkflag - 16 + 4]);
3133 else
3134 3 scr->ffcs[i].data = scr->secretcombo[checkflag - 16 + 4];
3135 12 scr->ffcs[i].cset = scr->secretcset[checkflag-16+4];
3136 12 }
3137 494906 }
3138 524745 }
3139
3140 endhe:
3141
3142
1/2
✓ Branch 0 taken 18007 times.
✗ Branch 1 not taken.
18007 if (scr->flags4&fDISABLETIME) //Finish timed warp if 'Secrets Disable Timed Warp'
3143 {
3144 if (from_active_screen)
3145 activated_timed_warp = true;
3146 scr->timedwarptics = 0;
3147 }
3148 18007 }
3149
3150 // x,y are world coordinates.
3151 // Returns true if there is a flag (either combo, screen, or ffc) at (x, y).
3152 // Out parameters will be set if the flag is Trigger->Self, which modifies how secrets will be triggered.
3153 13508239 static bool has_flag_trigger(int32_t x, int32_t y, int32_t flag, rpos_t& out_rpos, bool& out_single16)
3154 {
3155
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13508239 times.
13508239 if (!is_in_world_bounds(x, y)) return false;
3156
3157 13508239 bool found_cflag = false;
3158 13508239 bool found_nflag = false;
3159 13508239 bool single16 = false;
3160 13508239 rpos_t rpos = rpos_t::None;
3161
3162
2/2
✓ Branch 0 taken 13506155 times.
✓ Branch 1 taken 94545481 times.
108051636 for (int32_t layer = -1; layer < 6; layer++)
3163 {
3164
2/2
✓ Branch 0 taken 94543397 times.
✓ Branch 1 taken 2084 times.
94545481 if (MAPFLAG2(layer, x, y) == flag)
3165 {
3166 2084 found_nflag = true;
3167 2084 break;
3168 }
3169 94543397 }
3170
3171
2/2
✓ Branch 0 taken 13507935 times.
✓ Branch 1 taken 94556397 times.
108064332 for (int32_t layer = -1; layer < 6; layer++)
3172 {
3173
2/2
✓ Branch 0 taken 94556093 times.
✓ Branch 1 taken 304 times.
94556397 if (MAPCOMBOFLAG2(layer, x, y) == flag)
3174 {
3175 304 found_cflag = true;
3176 304 break;
3177 }
3178 94556093 }
3179
3180
2/2
✓ Branch 0 taken 94557673 times.
✓ Branch 1 taken 13508239 times.
108065912 for (int32_t i=-1; i<6; i++) // Look for Trigger->Self on all layers
3181 {
3182
2/2
✓ Branch 0 taken 94543085 times.
✓ Branch 1 taken 14588 times.
94557673 if (found_nflag) // Trigger->Self (a.k.a Singular) is inherent
3183 {
3184
3/4
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 14476 times.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
14588 if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE) && (MAPFLAG2(i, x, y) == flag))
3185 {
3186 112 rpos = COMBOPOS_REGION(x, y);
3187 112 }
3188
3/4
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 14424 times.
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
14476 else if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE16) && (MAPFLAG2(i, x, y) == flag))
3189 {
3190 52 rpos = COMBOPOS_REGION(x, y);
3191 52 single16 = true;
3192 52 }
3193 14588 }
3194
3195
2/2
✓ Branch 0 taken 94555545 times.
✓ Branch 1 taken 2128 times.
94557673 if (found_cflag) // Trigger->Self (a.k.a Singular) is non-inherent
3196 {
3197
3/4
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 1873 times.
✓ Branch 2 taken 255 times.
✗ Branch 3 not taken.
2128 if ((MAPFLAG2(i, x, y) == mfSINGLE) && (MAPCOMBOFLAG2(i, x, y) == flag))
3198 {
3199 255 rpos = COMBOPOS_REGION(x, y);
3200 255 }
3201
3/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 1853 times.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
1873 else if ((MAPFLAG2(i, x, y) == mfSINGLE16) && (MAPCOMBOFLAG2(i, x, y) == flag))
3202 {
3203 20 rpos = COMBOPOS_REGION(x, y);
3204 20 single16 = true;
3205 20 }
3206 2128 }
3207 94557673 }
3208
3209 13508239 out_rpos = rpos;
3210 13508239 out_single16 = single16;
3211
4/4
✓ Branch 0 taken 13506155 times.
✓ Branch 1 taken 2084 times.
✓ Branch 2 taken 13505853 times.
✓ Branch 3 taken 302 times.
13508239 return found_nflag || found_cflag || MAPFFCOMBOFLAG(x,y) == flag;
3212 13508239 }
3213
3214 4457867 bool trigger_secrets_if_flag(int32_t x, int32_t y, int32_t flag, bool setflag)
3215 {
3216
8/8
✓ Branch 0 taken 4457627 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 4455730 times.
✓ Branch 3 taken 1897 times.
✓ Branch 4 taken 4455210 times.
✓ Branch 5 taken 520 times.
✓ Branch 6 taken 952 times.
✓ Branch 7 taken 4454258 times.
4457867 if (x < -16 || y < -16 || x >= world_w || y >= world_h) return false;
3217
3218 4454258 mapscr* scr = NULL;
3219 4454258 int32_t screen = -1;
3220 4454258 rpos_t trigger_rpos = rpos_t::None;
3221 4454258 bool single16 = false;
3222
3223 4454258 std::vector<std::pair<int, int>> coords;
3224
1/2
✓ Branch 0 taken 4454258 times.
✗ Branch 1 not taken.
4454258 coords.push_back({x, y});
3225
1/2
✓ Branch 0 taken 4454258 times.
✗ Branch 1 not taken.
4454258 coords.push_back({x + 15, y});
3226
1/2
✓ Branch 0 taken 4454258 times.
✗ Branch 1 not taken.
4454258 coords.push_back({x, y + 15});
3227
1/2
✓ Branch 0 taken 4454258 times.
✗ Branch 1 not taken.
4454258 coords.push_back({x + 15, y + 15});
3228 4454258 std::vector<rpos_t> rposes_seen;
3229
2/2
✓ Branch 0 taken 4451861 times.
✓ Branch 1 taken 17811750 times.
84483617 for (auto [x, y] : coords)
3230 {
3231
2/4
✓ Branch 0 taken 17811750 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17811750 times.
✗ Branch 3 not taken.
35623500 rpos_t rpos = COMBOPOS_REGION_B(x, y);
3232
2/2
✓ Branch 0 taken 17599367 times.
✓ Branch 1 taken 212383 times.
17811750 if (rpos == rpos_t::None)
3233 212383 continue;
3234
3235
4/6
✓ Branch 0 taken 17599367 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17599367 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 17599356 times.
35198734 if (MAPFFCOMBOFLAG(x, y) == flag)
3236 {
3237
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
22 screen = get_screen_for_world_xy(x, y);
3238 11 break;
3239 }
3240
3241 17599356 bool seen = false;
3242
2/2
✓ Branch 0 taken 13508239 times.
✓ Branch 1 taken 22128287 times.
35636526 for (rpos_t r : rposes_seen)
3243 {
3244
2/2
✓ Branch 0 taken 18037170 times.
✓ Branch 1 taken 4091117 times.
22128287 if (r == rpos)
3245 {
3246 4091117 seen = true;
3247 4091117 break;
3248 }
3249 }
3250
2/2
✓ Branch 0 taken 13508239 times.
✓ Branch 1 taken 4091117 times.
17599356 if (seen)
3251 4091117 continue;
3252
3253
1/2
✓ Branch 0 taken 13508239 times.
✗ Branch 1 not taken.
13508239 rposes_seen.push_back(rpos);
3254
4/6
✓ Branch 0 taken 13508239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13508239 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2386 times.
✓ Branch 5 taken 13505853 times.
27016478 if (has_flag_trigger(x, y, flag, trigger_rpos, single16))
3255 {
3256
2/4
✓ Branch 0 taken 2386 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2386 times.
✗ Branch 3 not taken.
4772 screen = get_screen_for_world_xy(x, y);
3257 2386 break;
3258 }
3259 }
3260
3261
3/4
✓ Branch 0 taken 2397 times.
✓ Branch 1 taken 4451861 times.
✓ Branch 2 taken 2397 times.
✗ Branch 3 not taken.
4454258 if (screen != -1) scr = get_scr(screen);
3262
2/2
✓ Branch 0 taken 2397 times.
✓ Branch 1 taken 4451861 times.
4454258 if (!scr) return false;
3263
3264
2/2
✓ Branch 0 taken 1958 times.
✓ Branch 1 taken 439 times.
2397 if (trigger_rpos == rpos_t::None)
3265 {
3266 1958 checktrigger = true;
3267
1/2
✓ Branch 0 taken 1958 times.
✗ Branch 1 not taken.
1958 trigger_secrets_for_screen(TriggerSource::Unspecified, screen);
3268 1958 }
3269 else
3270 {
3271 439 checktrigger = true;
3272
2/4
✓ Branch 0 taken 439 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 439 times.
✗ Branch 3 not taken.
439 trigger_secrets_for_screen(TriggerSource::Singular, scr, single16, RPOS_TO_POS(trigger_rpos));
3273 }
3274
3275
1/2
✓ Branch 0 taken 2397 times.
✗ Branch 1 not taken.
2397 sfx(scr->secretsfx);
3276
3277
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2391 times.
2397 if(scr->flags6&fTRIGGERFPERM)
3278 {
3279
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 int32_t flags_remaining = findtrigger(screen); //Normal flags
3280
3281
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (flags_remaining)
3282 {
3283
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 Z_eventlog("Hit All Triggers->Perm Secret not fulfilled (%d trigger flag%s remain).\n", flags_remaining, flags_remaining>1?"s":"");
3284 3 setflag=false;
3285 3 }
3286
3287 // Only actually trigger secrets now if 1) all triggers are gone and 2) QR qr_ALLTRIG_PERMSEC_NO_TEMP is off, in
3288 // which case only the screen state for mSECRET may be set below.
3289
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
6 if (!flags_remaining && !get_qr(qr_ALLTRIG_PERMSEC_NO_TEMP))
3290 {
3291 trigger_secrets_for_screen(TriggerSource::Unspecified, scr, scr->flags6&fTRIGGERF1631, -1);
3292 }
3293 6 }
3294
3295
5/6
✓ Branch 0 taken 2292 times.
✓ Branch 1 taken 105 times.
✓ Branch 2 taken 2292 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1108 times.
✓ Branch 5 taken 1184 times.
2397 if (setflag && canPermSecret(cur_dmap, screen))
3296
2/2
✓ Branch 0 taken 721 times.
✓ Branch 1 taken 463 times.
1905 if(!(scr->flags5&fTEMPSECRETS))
3297
1/2
✓ Branch 0 taken 721 times.
✗ Branch 1 not taken.
721 setmapflag(scr, mSECRET);
3298
3299 2397 return true;
3300 4457867 }
3301
3302 14809012 void update_slopes()
3303 {
3304
2/2
✓ Branch 0 taken 142356 times.
✓ Branch 1 taken 14809012 times.
14951368 for (auto& p : slopes)
3305 {
3306 142356 slope_object& s = p.second;
3307 142356 s.updateslope(); //sets old x/y poses
3308 }
3309 14809012 }
3310
3311 14402369 void update_freeform_combos()
3312 {
3313 14402369 ffscript_engine(false);
3314
2/2
✓ Branch 0 taken 24172 times.
✓ Branch 1 taken 14378197 times.
14402369 if ( !FFCore.system_suspend[susptUPDATEFFC] )
3315 {
3316 14378197 int wrap_right = world_w + 32;
3317 14378197 int wrap_bottom = world_h + 32;
3318
3319 485520731 for_every_ffc([&](const ffc_handle_t& ffc_handle) {
3320 471142534 mapscr* scr = ffc_handle.scr;
3321 471142534 ffcdata& thisffc = *ffc_handle.ffc;
3322
3323 // Combo 0?
3324
2/2
✓ Branch 0 taken 44992239 times.
✓ Branch 1 taken 426150295 times.
471142534 if(thisffc.data==0)
3325 426150295 return;
3326
3327 // Changer?
3328
2/2
✓ Branch 0 taken 543029 times.
✓ Branch 1 taken 44449210 times.
44992239 if(thisffc.flags&ffc_changer)
3329 543029 return;
3330
3331 // Stationary?
3332
2/2
✓ Branch 0 taken 9844 times.
✓ Branch 1 taken 44439366 times.
44449210 if(thisffc.flags&ffc_stationary)
3333 9844 return;
3334
3335 // Frozen because Hero's holding up an item?
3336
3/4
✓ Branch 0 taken 138282 times.
✓ Branch 1 taken 44301084 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 138282 times.
44439366 if(Hero.getHoldClk()>0 && (thisffc.flags&ffc_ignoreholdup)==0)
3337 138282 return;
3338
3339 // Check for changers
3340
2/2
✓ Branch 0 taken 29543786 times.
✓ Branch 1 taken 14757298 times.
44301084 if (thisffc.link==0)
3341 {
3342 442453159 for_some_ffcs([&](const ffc_handle_t& other_ffc_handle) {
3343
2/2
✓ Branch 0 taken 14755762 times.
✓ Branch 1 taken 412940099 times.
427695861 if (ffc_handle.id == other_ffc_handle.id)
3344 14755762 return true;
3345
3346 412940099 ffcdata& otherffc = *other_ffc_handle.ffc;
3347 // Combo 0?
3348
2/2
✓ Branch 0 taken 144689583 times.
✓ Branch 1 taken 268250516 times.
412940099 if(otherffc.data==0)
3349 268250516 return true;
3350
3351 // Not a changer?
3352
2/2
✓ Branch 0 taken 140701406 times.
✓ Branch 1 taken 3988177 times.
144689583 if(!(otherffc.flags&ffc_changer))
3353 140701406 return true;
3354
3355 // Ignore this changer?
3356
4/4
✓ Branch 0 taken 546579 times.
✓ Branch 1 taken 3441598 times.
✓ Branch 2 taken 299257 times.
✓ Branch 3 taken 3142341 times.
3988177 if((otherffc.x.getInt()==thisffc.changer_x&&otherffc.y.getInt()==thisffc.changer_y) || thisffc.flags&ffc_ignorechanger)
3357 845836 return true;
3358
3359
3/4
✓ Branch 0 taken 2721043 times.
✓ Branch 1 taken 421298 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3562 times.
3145903 if((isonline(thisffc.x.getZLong(), thisffc.y.getZLong(), thisffc.prev_changer_x, thisffc.prev_changer_y, otherffc.x.getZLong(), otherffc.y.getZLong()) || // Along the line, or...
3360 ( // At exactly the same position,
3361
2/2
✓ Branch 0 taken 208792 times.
✓ Branch 1 taken 2512251 times.
2721043 (thisffc.x==otherffc.x && thisffc.y==otherffc.y))
3362
2/2
✓ Branch 0 taken 2303459 times.
✓ Branch 1 taken 2512251 times.
208792 ||
3363 //or imprecision and close enough
3364
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
5024502 ( (thisffc.flags&ffc_imprecisionchanger) && ((abs(thisffc.x.getZLong() - otherffc.x.getZLong()) < 10000) && abs(thisffc.y.getZLong() - otherffc.y.getZLong()) < 10000) )
3365 )
3366 && //and...
3367
2/2
✓ Branch 0 taken 3562 times.
✓ Branch 1 taken 2721195 times.
2724757 (thisffc.prev_changer_x>-10000000 && thisffc.prev_changer_y>-10000000)) // This isn't the first frame on this screen
3368 {
3369 3562 zc_ffc_changer(thisffc, otherffc, ffc_handle.id, other_ffc_handle.id);
3370 3562 return false;
3371 }
3372
3373 2721195 return true;
3374 426679763 });
3375 14757298 }
3376
3377
2/2
✓ Branch 0 taken 29543786 times.
✓ Branch 1 taken 14757298 times.
44301084 ffcdata* linked_ffc = thisffc.link ? get_ffc_handle(thisffc.link - 1).ffc : nullptr;
3378
4/4
✓ Branch 0 taken 14757298 times.
✓ Branch 1 taken 29543786 times.
✓ Branch 2 taken 14680008 times.
✓ Branch 3 taken 14863778 times.
44301084 if (linked_ffc ? !linked_ffc->delay : !thisffc.delay)
3379 {
3380
4/4
✓ Branch 0 taken 182609 times.
✓ Branch 1 taken 14681169 times.
✓ Branch 2 taken 85331 times.
✓ Branch 3 taken 97278 times.
14863778 if(thisffc.link && (thisffc.link-1) != ffc_handle.id)
3381 {
3382 97278 thisffc.prev_changer_x = thisffc.x.getZLong();
3383 97278 thisffc.prev_changer_y = thisffc.y.getZLong();
3384 97278 thisffc.x += linked_ffc->vx;
3385 97278 thisffc.y += linked_ffc->vy;
3386 97278 }
3387 else
3388 {
3389 14766500 thisffc.prev_changer_x = thisffc.x.getZLong();
3390 14766500 thisffc.prev_changer_y = thisffc.y.getZLong();
3391 14766500 thisffc.x += thisffc.vx;
3392 14766500 thisffc.y += thisffc.vy;
3393 14766500 thisffc.vx += thisffc.ax;
3394 14766500 thisffc.vy += thisffc.ay;
3395
3396
3397
2/2
✓ Branch 0 taken 444046 times.
✓ Branch 1 taken 14322454 times.
14766500 if(get_qr(qr_OLD_FFC_SPEED_CAP))
3398 {
3399
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vx>128) thisffc.vx=128;
3400
3401
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vx<-128) thisffc.vx=-128;
3402
3403
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vy>128) thisffc.vy=128;
3404
3405
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vy<-128) thisffc.vy=-128;
3406 14322454 }
3407 }
3408 14863778 }
3409 else
3410 {
3411
3/4
✓ Branch 0 taken 1161 times.
✓ Branch 1 taken 76129 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1161 times.
29437306 if(!thisffc.link || (thisffc.link-1) == ffc_handle.id)
3412 76129 thisffc.delay--;
3413 }
3414
3415 // Check if the FFC's off the side of the screen
3416
3417 // Left
3418
2/2
✓ Branch 0 taken 10449 times.
✓ Branch 1 taken 14930619 times.
14941068 if(thisffc.x<-32)
3419 {
3420
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 10196 times.
10449 if(scr->flags6&fWRAPAROUNDFF)
3421 {
3422 253 thisffc.x = wrap_right+(thisffc.x+32);
3423 253 thisffc.solid_update(false);
3424 253 thisffc.prev_changer_y = thisffc.y.getZLong();
3425 // Re-enable previous changer
3426 253 thisffc.changer_x = -1000;
3427 253 thisffc.changer_y = -1000;
3428 253 }
3429
2/2
✓ Branch 0 taken 10127 times.
✓ Branch 1 taken 69 times.
10196 else if(thisffc.x<-64)
3430 {
3431 69 zc_ffc_set(thisffc, 0);
3432 69 thisffc.flags&=~ffc_carryover;
3433 69 }
3434 10449 }
3435 // Right
3436
2/2
✓ Branch 0 taken 14930438 times.
✓ Branch 1 taken 181 times.
14930619 else if(thisffc.x>=wrap_right)
3437 {
3438
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 53 times.
181 if(scr->flags6&fWRAPAROUNDFF)
3439 {
3440 128 thisffc.x = thisffc.x-wrap_right-32;
3441 128 thisffc.solid_update(false);
3442 128 thisffc.prev_changer_y = thisffc.y.getZLong();
3443 128 thisffc.changer_x = -1000;
3444 128 thisffc.changer_y = -1000;
3445 128 }
3446 else
3447 {
3448 53 zc_ffc_set(thisffc, 0);
3449 53 thisffc.flags&=~ffc_carryover;
3450 }
3451 181 }
3452
3453 // Top
3454
2/2
✓ Branch 0 taken 25480 times.
✓ Branch 1 taken 14915588 times.
14941068 if(thisffc.y<-32)
3455 {
3456
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 25472 times.
25480 if(scr->flags6&fWRAPAROUNDFF)
3457 {
3458 8 thisffc.y = wrap_bottom+(thisffc.y+32);
3459 8 thisffc.solid_update(false);
3460 8 thisffc.prev_changer_x = thisffc.x.getZLong();
3461 8 thisffc.changer_x = -1000;
3462 8 thisffc.changer_y = -1000;
3463 8 }
3464
2/2
✓ Branch 0 taken 25155 times.
✓ Branch 1 taken 317 times.
25472 else if(thisffc.y<-64)
3465 {
3466 317 zc_ffc_set(thisffc, 0);
3467 317 thisffc.flags&=~ffc_carryover;
3468 317 }
3469 25480 }
3470 // Bottom
3471
2/2
✓ Branch 0 taken 14914744 times.
✓ Branch 1 taken 844 times.
14915588 else if(thisffc.y>=wrap_bottom)
3472 {
3473
2/2
✓ Branch 0 taken 753 times.
✓ Branch 1 taken 91 times.
844 if(scr->flags6&fWRAPAROUNDFF)
3474 {
3475 753 thisffc.y = thisffc.y-wrap_bottom-32;
3476 753 thisffc.solid_update(false);
3477 753 thisffc.prev_changer_y = thisffc.x.getZLong();
3478 753 thisffc.changer_x = -1000;
3479 753 thisffc.changer_y = -1000;
3480 753 }
3481 else
3482 {
3483 91 zc_ffc_set(thisffc, 0);
3484 91 thisffc.flags&=~ffc_carryover;
3485 }
3486 844 }
3487 14941068 thisffc.solid_update();
3488 441782518 });
3489 14378197 }
3490 14402369 }
3491
3492 bool hitflag(int32_t x, int32_t y, int32_t flagtype, byte layers)
3493 {
3494 for(int q = 0; q < 7; ++q)
3495 {
3496 if(layers&(1<<q)) //if layer is to be checked
3497 if(MAPFLAG2(q-1,x,y)==flagtype||MAPCOMBOFLAG2(q-1,x,y)==flagtype) //matching flag
3498 return true;
3499 }
3500 return false;
3501 }
3502
3503 231 optional<int> nextscr(int screen, int dir)
3504 {
3505 231 auto [m, s] = nextscr2(cur_map, screen, dir);
3506
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231 times.
231 if (m == -1) return nullopt;
3507 462 return (m<<7) + s;
3508 231 }
3509
3510 1058 std::pair<int32_t, int32_t> nextscr2(int32_t dir)
3511 {
3512 1058 int32_t map = cur_map;
3513
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1058 times.
1058 int32_t screen = screenscrolling ? scrolling_hero_screen : hero_screen;
3514 1058 return nextscr2(map, screen, dir);
3515 }
3516
3517 5576 std::pair<int32_t, int32_t> nextscr2(int map, int screen, int32_t dir)
3518 {
3519 5576 screen = screen_index_direction(screen, (direction)dir);
3520
3521 // need to check for screens on other maps, 's' not valid, etc.
3522 5576 int32_t index = (hero_scr->sidewarpindex >> (dir*2))&3;
3523
3524 // Fun fact: when a scrolling warp is triggered, this function
3525 // is never even called! - Saf
3526
2/2
✓ Branch 0 taken 3326 times.
✓ Branch 1 taken 2250 times.
6120 if(hero_scr->sidewarptype[index] == 3) // scrolling warp
3527 {
3528
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 482 times.
✓ Branch 2 taken 525 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 697 times.
2250 switch(dir)
3529 {
3530 case up:
3531
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 399 times.
482 if(!(hero_scr->flags2&wfUP)) goto nowarp;
3532
3533 83 break;
3534
3535 case down:
3536
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 446 times.
525 if(!(hero_scr->flags2&wfDOWN)) goto nowarp;
3537
3538 79 break;
3539
3540 case left:
3541
2/2
✓ Branch 0 taken 209 times.
✓ Branch 1 taken 337 times.
546 if(!(hero_scr->flags2&wfLEFT)) goto nowarp;
3542
3543 209 break;
3544
3545 case right:
3546
2/2
✓ Branch 0 taken 173 times.
✓ Branch 1 taken 524 times.
697 if(!(hero_scr->flags2&wfRIGHT)) goto nowarp;
3547
3548 173 break;
3549 }
3550
3551 544 map = DMaps[hero_scr->sidewarpdmap[index]].map;
3552 544 screen = hero_scr->sidewarpscr[index] + DMaps[hero_scr->sidewarpdmap[index]].xoff;
3553 544 }
3554
3555 nowarp:
3556
4/4
✓ Branch 0 taken 5512 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 5400 times.
5576 if(screen<0||screen>=128)
3557 176 return {-1, -1};
3558
3559 5400 return {map, screen};
3560 5576 }
3561
3562 403 optional<int> nextscr_mi(int mi, int dir)
3563 {
3564 403 int map = mi/MAPSCRSNORMAL;
3565 403 int screen = mi%MAPSCRSNORMAL;
3566 403 auto [m, s] = nextscr2(map, screen, dir);
3567
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 402 times.
403 if (m == -1) return nullopt;
3568 804 return (m<<7) + s;
3569 403 }
3570
3571 2114 void bombdoor(int32_t x,int32_t y)
3572 {
3573
2/2
✓ Branch 0 taken 2094 times.
✓ Branch 1 taken 20 times.
2114 if (!is_in_world_bounds(x, y))
3574 20 return;
3575
3576 2094 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
3577 2094 mapscr* scr = rpos_handle.scr;
3578 2094 int screen = scr->screen;
3579 2902 auto [x0, y0] = translate_screen_coordinates_to_world(rpos_handle.screen);
3580 #define CHECK_RECT(x,y,rx1,ry1,rx2,ry2) (isinRect(x,y,x0+rx1,y0+ry1,x0+rx2,y0+ry2))
3581
3582
12/12
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 2015 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 69 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 69 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 69 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 69 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 69 times.
2094 if(scr->door[0]==dBOMB && CHECK_RECT(x,y,100,0,139,48))
3583 {
3584 69 scr->door[0]=dBOMBED;
3585 69 putdoor(scr, scrollbuf, 0, dBOMBED);
3586 69 setmapflag(scr, mDOOR_UP);
3587 69 markBmap(-1, screen);
3588
3589
1/2
✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
69 if(auto v = nextscr(screen, up))
3590 {
3591 69 setmapflag_mi(*v, mDOOR_DOWN);
3592 69 markBmap(-1,*v-(get_currdmap()<<7));
3593 69 }
3594 69 }
3595
3596
12/12
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2045 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 39 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 39 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 39 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 39 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 39 times.
2094 if(scr->door[1]==dBOMB && CHECK_RECT(x,y,100,112,139,176))
3597 {
3598 39 scr->door[1]=dBOMBED;
3599 39 putdoor(scr, scrollbuf, 1, dBOMBED);
3600 39 setmapflag(scr, mDOOR_DOWN);
3601 39 markBmap(-1, rpos_handle.screen);
3602
3603
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if(auto v = nextscr(rpos_handle.screen, down))
3604 {
3605 39 setmapflag_mi(*v, mDOOR_UP);
3606 39 markBmap(-1,*v-(get_currdmap()<<7));
3607 39 }
3608 39 }
3609
3610
12/12
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 2027 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 51 times.
✓ Branch 8 taken 16 times.
✓ Branch 9 taken 51 times.
✓ Branch 10 taken 16 times.
✓ Branch 11 taken 51 times.
2094 if(scr->door[2]==dBOMB && CHECK_RECT(x,y,0,60,48,98))
3611 {
3612 51 scr->door[2]=dBOMBED;
3613 51 putdoor(scr, scrollbuf, 2, dBOMBED);
3614 51 setmapflag(scr, mDOOR_LEFT);
3615 51 markBmap(-1, rpos_handle.screen);
3616
3617
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(auto v = nextscr(rpos_handle.screen, left))
3618 {
3619 51 setmapflag_mi(*v, mDOOR_RIGHT);
3620 51 markBmap(-1,*v-(get_currdmap()<<7));
3621 51 }
3622 51 }
3623
3624
12/12
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 2008 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 72 times.
✓ Branch 6 taken 14 times.
✓ Branch 7 taken 72 times.
✓ Branch 8 taken 14 times.
✓ Branch 9 taken 72 times.
✓ Branch 10 taken 14 times.
✓ Branch 11 taken 72 times.
2094 if(scr->door[3]==dBOMB && CHECK_RECT(x,y,192,60,240,98))
3625 {
3626 72 scr->door[3]=dBOMBED;
3627 72 putdoor(scr, scrollbuf, 3, dBOMBED);
3628 72 setmapflag(scr, mDOOR_RIGHT);
3629 72 markBmap(-1, rpos_handle.screen);
3630
3631
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if(auto v = nextscr(rpos_handle.screen, right))
3632 {
3633 72 setmapflag_mi(*v, mDOOR_LEFT);
3634 72 markBmap(-1,*v-(get_currdmap()<<7));
3635 72 }
3636 72 }
3637 2114 }
3638
3639 6384306538 void draw_cmb(BITMAP* dest, int32_t x, int32_t y, int32_t cid, int32_t cset,
3640 bool over, bool transp)
3641 {
3642 6384306538 auto& cmb = combobuf[cid];
3643
2/2
✓ Branch 0 taken 90743 times.
✓ Branch 1 taken 6384215795 times.
6384306538 if(cmb.animflags & AF_EDITOR_ONLY)
3644 90743 return;
3645
2/2
✓ Branch 0 taken 3309354865 times.
✓ Branch 1 taken 3074860930 times.
6384215795 if(over)
3646 {
3647
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3309354865 times.
3309354865 if(cmb.animflags & AF_TRANSPARENT)
3648 transp = !transp;
3649
2/2
✓ Branch 0 taken 319148412 times.
✓ Branch 1 taken 2990206453 times.
3309354865 if(transp)
3650 319148412 overcombotranslucent(dest, x, y, cid, cset, 128);
3651 2990206453 else overcombo(dest, x, y, cid, cset);
3652 3309354865 }
3653 3074860930 else putcombo(dest, x, y, cid, cset);
3654 6384306538 }
3655 6384314986 void draw_cmb_pos(BITMAP* dest, int32_t x, int32_t y, rpos_t rpos, int32_t cid,
3656 int32_t cset, byte layer, bool over, bool transp)
3657 {
3658
2/2
✓ Branch 0 taken 750736355 times.
✓ Branch 1 taken 5633578631 times.
6384314986 if (rpos != rpos_t::None)
3659 {
3660 5633578631 rpos_t plrpos = COMBOPOS_REGION_B(Hero.x+8, Hero.y+8);
3661
2/2
✓ Branch 0 taken 749524 times.
✓ Branch 1 taken 5632829107 times.
5633578631 if (plrpos != rpos_t::None)
3662 {
3663 5632829107 bool dosw = false;
3664
4/4
✓ Branch 0 taken 52860 times.
✓ Branch 1 taken 5632776247 times.
✓ Branch 2 taken 44412 times.
✓ Branch 3 taken 8448 times.
5632829107 if (rpos == hooked_comborpos && (hooked_layerbits & (1<<layer)))
3665 {
3666
1/2
✓ Branch 0 taken 8448 times.
✗ Branch 1 not taken.
8448 if(hooked_undercombos[layer] > -1)
3667 {
3668 draw_cmb(dest, x, y,
3669 hooked_undercombos[layer], hooked_undercombos[layer+7], over, transp);
3670 }
3671 8448 dosw = true;
3672 8448 }
3673
4/4
✓ Branch 0 taken 31973777 times.
✓ Branch 1 taken 5600846882 times.
✓ Branch 2 taken 8448 times.
✓ Branch 3 taken 31965329 times.
5632820659 else if (rpos == plrpos && (hooked_layerbits & (1<<(layer+8))))
3674 {
3675 8448 dosw = true;
3676 8448 }
3677
2/2
✓ Branch 0 taken 5632812211 times.
✓ Branch 1 taken 16896 times.
5632829107 if (dosw)
3678 {
3679
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 16896 times.
✗ Branch 3 not taken.
16896 switch (Hero.switchhookstyle)
3680 {
3681 default: case swPOOF:
3682 break; //Nothing special here
3683 case swFLICKER:
3684 {
3685
2/2
✓ Branch 0 taken 8448 times.
✓ Branch 1 taken 8448 times.
16896 if(abs(Hero.switchhookclk-33)&0b1000)
3686 8448 break; //Drawn this frame
3687 8448 return; //Not drawn this frame
3688 }
3689 case swRISE:
3690 {
3691 //Draw rising up
3692 y -= 8-(abs(Hero.switchhookclk-32)/4);
3693 break;
3694 }
3695 }
3696 8448 }
3697 5632820659 }
3698 5633570183 }
3699
3700 6384306538 draw_cmb(dest, x, y, cid, cset, over, transp);
3701 6384314986 }
3702
3703 // `draw_cmb_pos` only does meaningful work if the combo being drawn is within the bounds of
3704 // the `bmp` bitmap. However, even getting to the point where `puttile16` (for example) knows
3705 // to cull is somewhat expensive. Since it can only draw 16x16 pixels, we can do the equivalent
3706 // culling here by determining the rows/columns that are within the bitmap bounds. This nets
3707 // on the order of ~30 FPS in uncapped mode on my machine, depending on the viewport/region size.
3708 //
3709 // These two inequalities must be true for `draw_cmb_pos` to do anything useful:
3710 //
3711 // -16 < comboPositionX*16 + x < bitmapWidth
3712 // -16 < comboPositionY*16 + y < bitmapHeight
3713 //
3714 // The following start/end values are derived directly from the above.
3715 //
3716 // `x` and `y` are the offsets the combos will be drawn into the bitmap.
3717 39481806 static void get_bounds_for_draw_cmb_calls(BITMAP* bmp, int x, int y, int& start_x, int& end_x, int& start_y, int& end_y)
3718 {
3719 // if (bmp->clip)
3720 // {
3721 // start_x = MAX(0, ceil((bmp->cl - 15 - x) / 16.0));
3722 // end_x = MIN(16, ceil((bmp->cr - x) / 16.0));
3723 // start_y = MAX(0, ceil((bmp->ct - 15 - y) / 16.0));
3724 // end_y = MIN(11, ceil((bmp->cb - y) / 16.0));
3725 // return;
3726 // }
3727
3728
2/2
✓ Branch 0 taken 2169310 times.
✓ Branch 1 taken 37312496 times.
39481806 start_x = MAX(0, ceil((-15 - x) / 16.0));
3729
2/2
✓ Branch 0 taken 2178501 times.
✓ Branch 1 taken 37303305 times.
39481806 end_x = MIN(16, ceil((bmp->w - x) / 16.0));
3730
2/2
✓ Branch 0 taken 38092548 times.
✓ Branch 1 taken 1389258 times.
39481806 start_y = MAX(0, ceil((-15 - y) / 16.0));
3731
2/2
✓ Branch 0 taken 1678576 times.
✓ Branch 1 taken 37803230 times.
39481806 end_y = MIN(11, ceil((bmp->h - y) / 16.0));
3732 39481806 }
3733
3734 186960519 void do_ffc_layer(BITMAP* bmp, int32_t layer, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3735 {
3736
1/2
✓ Branch 0 taken 186960519 times.
✗ Branch 1 not taken.
186960519 if(!show_ffcs) return;
3737 186960519 mapscr* scr = screen_handle.scr;
3738 186960519 mapscr* base_scr = screen_handle.base_scr;
3739
3740 186960519 y += playing_field_offset;
3741
3742 186960519 bool is_bg_layer = layer < -1;
3743
2/2
✓ Branch 0 taken 33926573 times.
✓ Branch 1 taken 153033946 times.
186960519 int real_layer = is_bg_layer ? abs(layer) : layer;
3744
2/2
✓ Branch 0 taken 186960519 times.
✓ Branch 1 taken 5581189773 times.
5768150292 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3745 {
3746
2/2
✓ Branch 0 taken 5375692187 times.
✓ Branch 1 taken 205497586 times.
5581189773 if (base_scr->ffcs[i].data == 0)
3747 5375692187 continue;
3748
4/4
✓ Branch 0 taken 37360942 times.
✓ Branch 1 taken 168136644 times.
✓ Branch 2 taken 18682952 times.
✓ Branch 3 taken 18677990 times.
205497586 if(real_layer == 2 && (is_bg_layer != XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG)))
3749 18677990 continue;
3750
4/4
✓ Branch 0 taken 37360942 times.
✓ Branch 1 taken 149458654 times.
✓ Branch 2 taken 18682952 times.
✓ Branch 3 taken 18677990 times.
186819596 else if (real_layer == 3 && (is_bg_layer != XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)))
3751 18677990 continue;
3752
4/4
✓ Branch 0 taken 149463616 times.
✓ Branch 1 taken 18677990 times.
✓ Branch 2 taken 18682952 times.
✓ Branch 3 taken 130780664 times.
168141606 if (real_layer > -1 && base_scr->ffcs[i].layer != real_layer)
3753 130780664 continue;
3754
3755
6/6
✓ Branch 0 taken 3008970 times.
✓ Branch 1 taken 34351972 times.
✓ Branch 2 taken 5110 times.
✓ Branch 3 taken 3003860 times.
✓ Branch 4 taken 2626 times.
✓ Branch 5 taken 2484 times.
37360942 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3756 2484 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3757
3758 37358458 base_scr->ffcs[i].draw_ffc(bmp, x, y, (layer==-1));
3759 37358458 }
3760 186960519 }
3761 170937415 void _do_current_ffc_layer(BITMAP* bmp, int32_t layer)
3762 {
3763
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 170937415 times.
170937415 if(!show_ffcs) return;
3764 346453052 for_every_base_screen_in_region([&](mapscr* base_scr, unsigned int region_scr_x, unsigned int region_scr_y) {
3765 175515637 screen_handle_t handle = {base_scr, base_scr, base_scr->screen, 0};
3766 175515637 do_ffc_layer(bmp, layer, handle, 0, 0);
3767 175515637 });
3768 170937415 }
3769 75616832 void do_scrolling_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3770 {
3771 75616832 mapscr* scr = screen_handle.scr;
3772 75616832 mapscr* base_scr = screen_handle.base_scr;
3773
3774
4/4
✓ Branch 0 taken 60951502 times.
✓ Branch 1 taken 14665330 times.
✓ Branch 2 taken 14665330 times.
✓ Branch 3 taken 75616832 times.
75616832 if (type == -3 || type == -4)
3775 {
3776 29330660 y += playing_field_offset;
3777
3778
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
29330660 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3779 {
3780 if (base_scr->ffcs[i].data == 0)
3781 continue;
3782
3783 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3784 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3785
3786 base_scr->ffcs[i].draw_ffc(bmp, x, y, (type==-4));
3787 }
3788 return;
3789 }
3790
3791 75616832 x -= viewport.x;
3792 75616832 y -= viewport.y - playing_field_offset;
3793
3794 75616832 bool over = true, transp = false;
3795 75616832 int layer = screen_handle.layer;
3796
3797
7/8
✓ Branch 0 taken 55151077 times.
✓ Branch 1 taken 20465755 times.
✓ Branch 2 taken 13148696 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 34185284 times.
✓ Branch 5 taken 20965793 times.
✓ Branch 6 taken 3060005 times.
✓ Branch 7 taken 4257054 times.
75616832 switch(type ? type : layer)
3798 {
3799 case -2: //push blocks
3800
2/2
✓ Branch 0 taken 19519954 times.
✓ Branch 1 taken 14665330 times.
34185284 if (scr)
3801 {
3802
2/2
✓ Branch 0 taken 3435511904 times.
✓ Branch 1 taken 23710596 times.
3435005872 for(int32_t i=0; i<176; i++)
3803 {
3804 3435511904 int32_t mf=scr->sflag[i], mf2 = combobuf[scr->data[i]].flag;
3805
3806
10/10
✓ Branch 0 taken 3435341560 times.
✓ Branch 1 taken 170344 times.
✓ Branch 2 taken 3433869588 times.
✓ Branch 3 taken 1471972 times.
✓ Branch 4 taken 3433240605 times.
✓ Branch 5 taken 628983 times.
✓ Branch 6 taken 24420859 times.
✓ Branch 7 taken 3408819746 times.
✓ Branch 8 taken 42762999 times.
✓ Branch 9 taken 16705821 times.
3472559372 if(mf==mfPUSHUD || mf==mfPUSH4 || mf==mfPUSHED || ((mf>=mfPUSHLR)&&(mf<=mfPUSHRINS))
3807
6/8
✓ Branch 0 taken 3430359076 times.
✓ Branch 1 taken 21539330 times.
✓ Branch 2 taken 3430359076 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3430359076 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 37047468 times.
✓ Branch 7 taken 3393311608 times.
3433240605 || mf2==mfPUSHUD || mf2==mfPUSH4 || mf2==mfPUSHED || ((mf2>=mfPUSHLR)&&(mf2<=mfPUSHRINS)))
3808 {
3809
4/4
✓ Branch 0 taken 4772507 times.
✓ Branch 1 taken 695982 times.
✓ Branch 2 taken 3657 times.
✓ Branch 3 taken 4768850 times.
90994487 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3810 5468489 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3811 5468489 }
3812 3415485918 }
3813 23710596 }
3814 38375926 return;
3815
3816 case -1: //over combo
3817
1/2
✓ Branch 0 taken 20965793 times.
✗ Branch 1 not taken.
20965793 if (scr)
3818 {
3819
2/2
✓ Branch 0 taken 3689979568 times.
✓ Branch 1 taken 20965793 times.
3710945361 for(int32_t i=0; i<176; i++)
3820 {
3821
2/2
✓ Branch 0 taken 3670703512 times.
✓ Branch 1 taken 19276056 times.
3689979568 if(combo_class_buf[combobuf[scr->data[i]].type].overhead)
3822 {
3823
4/4
✓ Branch 0 taken 15523213 times.
✓ Branch 1 taken 3752843 times.
✓ Branch 2 taken 22320 times.
✓ Branch 3 taken 15500893 times.
19276056 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3824 19276056 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3825 19276056 }
3826 3689979568 }
3827 20965793 }
3828 20965793 return;
3829
3830 case 1:
3831 case 4:
3832 case 5:
3833 case 6:
3834
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 13148696 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
13148696 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3835 {
3836
1/2
✓ Branch 0 taken 13148696 times.
✗ Branch 1 not taken.
13148696 if (scr)
3837 {
3838
2/2
✓ Branch 0 taken 11489485 times.
✓ Branch 1 taken 1659211 times.
13148696 if(base_scr->layeropacity[layer-1]!=255)
3839 1659211 transp = true;
3840 13148696 break;
3841 }
3842 }
3843 return;
3844
3845 case 2:
3846
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3060005 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3060005 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3847 {
3848
1/2
✓ Branch 0 taken 3060005 times.
✗ Branch 1 not taken.
3060005 if (scr)
3849 {
3850
2/2
✓ Branch 0 taken 2840408 times.
✓ Branch 1 taken 219597 times.
3060005 if(base_scr->layeropacity[layer-1]!=255)
3851 219597 transp = true;
3852
3853
2/2
✓ Branch 0 taken 2931096 times.
✓ Branch 1 taken 128909 times.
3060005 if(XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3854 128909 over = false;
3855
3856 3060005 break;
3857 }
3858 }
3859 return;
3860
3861 case 3:
3862
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4257054 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4257054 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3863 {
3864
1/2
✓ Branch 0 taken 4257054 times.
✗ Branch 1 not taken.
4257054 if (scr)
3865 {
3866
2/2
✓ Branch 0 taken 4183341 times.
✓ Branch 1 taken 73713 times.
4257054 if(base_scr->layeropacity[layer-1]!=255)
3867 73713 transp = true;
3868
3869
2/2
✓ Branch 0 taken 36654 times.
✓ Branch 1 taken 60483 times.
4257054 if(XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
3870
2/2
✓ Branch 0 taken 97137 times.
✓ Branch 1 taken 4159917 times.
4257054 && !XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3871 60483 over = false;
3872
3873 4257054 break;
3874 }
3875 }
3876 return;
3877 }
3878
3879 int start_x, end_x, start_y, end_y;
3880 20465755 get_bounds_for_draw_cmb_calls(bmp, x, y, start_x, end_x, start_y, end_y);
3881
2/2
✓ Branch 0 taken 20465755 times.
✓ Branch 1 taken 216989831 times.
237455586 for (int cy = start_y; cy < end_y; cy++)
3882 {
3883
2/2
✓ Branch 0 taken 3283735479 times.
✓ Branch 1 taken 216989831 times.
3500725310 for (int cx = start_x; cx < end_x; cx++)
3884 {
3885 3283735479 int i = cx + cy*16;
3886
4/4
✓ Branch 0 taken 2905552252 times.
✓ Branch 1 taken 378183227 times.
✓ Branch 2 taken 10227360 times.
✓ Branch 3 taken 2895324892 times.
3283735479 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3887 3283735479 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, over, transp);
3888 3283735479 }
3889 216989831 }
3890 60951502 }
3891
3892 269002203 bool lenscheck(mapscr* scr, int layer)
3893 {
3894
4/4
✓ Branch 0 taken 268823255 times.
✓ Branch 1 taken 178948 times.
✓ Branch 2 taken 178948 times.
✓ Branch 3 taken 269002203 times.
269002203 if(layer < 0 || layer > 6) return true;
3895
2/2
✓ Branch 0 taken 259588626 times.
✓ Branch 1 taken 9413577 times.
269002203 if(get_qr(qr_OLD_LENS_LAYEREFFECT))
3896 {
3897
2/2
✓ Branch 0 taken 209710465 times.
✓ Branch 1 taken 49878161 times.
259588626 if(!layer) return true;
3898
8/8
✓ Branch 0 taken 34922371 times.
✓ Branch 1 taken 174788094 times.
✓ Branch 2 taken 258970 times.
✓ Branch 3 taken 34663401 times.
✓ Branch 4 taken 143758 times.
✓ Branch 5 taken 163336 times.
✓ Branch 6 taken 326536 times.
✓ Branch 7 taken 34480623 times.
209710465 if((layer==(int32_t)(scr->lens_layer&7)+1) && ((scr->lens_layer&llLENSSHOWS && !lensclk) || (scr->lens_layer&llLENSHIDES && lensclk)))
3899 489872 return false;
3900 209268717 }
3901 else
3902 {
3903
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9413577 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9413577 times.
9413577 if((lensclk ? scr->lens_hide : scr->lens_show) & (1<<layer))
3904 return false;
3905 }
3906 218682294 return true;
3907 268823255 }
3908
3909 156158207 void do_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3910 {
3911 156158207 bool showlayer = true;
3912 156158207 mapscr* base_scr = screen_handle.base_scr;
3913 156158207 int layer = screen_handle.layer;
3914
2/2
✓ Branch 0 taken 42084449 times.
✓ Branch 1 taken 114073758 times.
156158207 int target = type ? type : layer;
3915
3/4
✓ Branch 0 taken 114073758 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20230988 times.
✓ Branch 3 taken 21853461 times.
156158207 switch(target)
3916 {
3917 case -2:
3918
1/2
✓ Branch 0 taken 20230988 times.
✗ Branch 1 not taken.
20230988 if(!show_layer_push)
3919 showlayer = false;
3920 20230988 break;
3921
3922 case -1:
3923
1/2
✓ Branch 0 taken 21853461 times.
✗ Branch 1 not taken.
21853461 if(!show_layer_over)
3924 showlayer = false;
3925 21853461 break;
3926
3927 case 1: case 2: case 3:
3928 case 4: case 5: case 6:
3929 114073758 showlayer = show_layers[target];
3930 114073758 break;
3931 }
3932
3933
2/2
✓ Branch 0 taken 42084449 times.
✓ Branch 1 taken 114073758 times.
156158207 if(!type)
3934 {
3935
2/2
✓ Branch 0 taken 113937560 times.
✓ Branch 1 taken 136198 times.
114073758 if(!lenscheck(base_scr,layer))
3936 136198 showlayer = false;
3937 114073758 }
3938
3939
2/2
✓ Branch 0 taken 136198 times.
✓ Branch 1 taken 156022009 times.
156158207 if(showlayer)
3940 {
3941
6/6
✓ Branch 0 taken 61007625 times.
✓ Branch 1 taken 95014384 times.
✓ Branch 2 taken 20521878 times.
✓ Branch 3 taken 40485747 times.
✓ Branch 4 taken 56123 times.
✓ Branch 5 taken 20465755 times.
156022009 if (screen_handle.scr && (type || !(base_scr->hidelayers & (1 << (layer)))))
3942 {
3943 60951502 do_scrolling_layer(bmp, type, screen_handle, x, y);
3944
4/4
✓ Branch 0 taken 20465755 times.
✓ Branch 1 taken 40485747 times.
✓ Branch 2 taken 19233761 times.
✓ Branch 3 taken 1231994 times.
60951502 if(!type && !get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
3945
2/2
✓ Branch 0 taken 1231418 times.
✓ Branch 1 taken 576 times.
1232570 if(mblock2.draw(bmp,layer))
3946 576 do_primitives(bmp, SPLAYER_MOVINGBLOCK);
3947 60951502 }
3948 156022009 }
3949 156158207 }
3950
3951 103025421 void do_layer_primitives(BITMAP *bmp, int32_t layer)
3952 {
3953 103025421 bool showlayer = true;
3954
3955
2/4
✓ Branch 0 taken 103025421 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 103025421 times.
103025421 if(layer >= 0 && layer <= 6)
3956 {
3957 103025421 showlayer = show_layers[layer];
3958
3959
2/2
✓ Branch 0 taken 102898819 times.
✓ Branch 1 taken 126602 times.
103025421 if(!lenscheck(origin_scr,layer))
3960 126602 showlayer = false;
3961 103025421 }
3962
3963
2/2
✓ Branch 0 taken 126602 times.
✓ Branch 1 taken 102898819 times.
103025421 if (showlayer)
3964 102898819 do_primitives(bmp, layer);
3965 103025421 }
3966
3967 // Called by do_walkflags
3968 void put_walkflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
3969 {
3970 newcombo const &c = combobuf[cmbdat];
3971
3972 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
3973
3974 int32_t xx = x-xofs;
3975 int32_t yy = y+playing_field_offset-yofs;
3976
3977 int32_t bridgedetected = 0;
3978
3979 for(int32_t i=0; i<4; i++)
3980 {
3981 int32_t tx=((i&2)<<2)+xx - viewport.x;
3982 int32_t ty=((i&1)<<3)+yy - viewport.y;
3983 int32_t tx2=((i&2)<<2)+x - viewport.x;
3984 int32_t ty2=((i&1)<<3)+y - viewport.y;
3985 for (int32_t j = lyr-1; j <= 1; j++)
3986 {
3987 if (get_qr(qr_OLD_BRIDGE_COMBOS))
3988 {
3989 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && !_walkflag_layer(tx2,ty2,j))
3990 {
3991 bridgedetected |= (1<<i);
3992 }
3993 }
3994 else
3995 {
3996 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && _effectflag_layer(tx2,ty2,j))
3997 {
3998 bridgedetected |= (1<<i);
3999 }
4000 }
4001 }
4002 if ((bridgedetected & (1<<i)))
4003 {
4004 if (i >= 3) break;
4005 else continue;
4006 }
4007 bool doladdercheck = true;
4008
4009 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4010 {
4011 for(int32_t k=0; k<8; k+=2)
4012 for(int32_t j=0; j<8; j+=2)
4013 if(((k+j)/2)%2)
4014 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,makecol(85,85,255));
4015 }
4016 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4017 {
4018 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4019 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4020 rectfill(dest,tx,ty,tx+7,ty+7,makecol(85,85,255));
4021 else rectfill(dest,tx,ty,tx+7,ty+7,makecol(170,170,170));
4022 }
4023
4024 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4025 {
4026 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4027 {
4028 for(int32_t k=0; k<8; k+=2)
4029 for(int32_t j=0; j<8; j+=2)
4030 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,((k+j)/2)%2 ? makecol(165,105,8) : makecol(170,170,170));
4031 }
4032 else
4033 {
4034 int32_t color = makecol(178,36,36);
4035
4036 if(isstepable(cmbdat)&& (!doladdercheck))
4037 color=makecol(165,105,8);
4038 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4039 color=makecol(170,170,170);
4040
4041 rectfill(dest,tx,ty,tx+7,ty+7,color);
4042 }
4043 }
4044 }
4045
4046 // Draw damage combos
4047 bool dmg = combo_class_buf[combobuf[MAPCOMBO2(-1,xx,yy)].type].modify_hp_amount
4048 || combo_class_buf[combobuf[MAPCOMBO2(0,xx,yy)].type].modify_hp_amount
4049 || combo_class_buf[combobuf[MAPCOMBO2(1,xx,yy)].type].modify_hp_amount;
4050
4051 if(dmg)
4052 {
4053 int32_t color = makecol(255,255,0);
4054 if (bridgedetected <= 0)
4055 {
4056 for(int32_t k=0; k<16; k+=2)
4057 for(int32_t j=0; j<16; j+=2)
4058 if(((k+j)/2)%2)
4059 {
4060 int32_t x0 = x - viewport.x;
4061 int32_t y0 = y - viewport.y;
4062 rectfill(dest,x0+k,y0+j,x0+k+1,y0+j+1,color);
4063 }
4064 }
4065 else
4066 {
4067 for(int32_t i=0; i<4; i++)
4068 {
4069 if (!(bridgedetected & (1<<i)))
4070 {
4071 int32_t tx=((i&2)<<2)+x - viewport.x;
4072 int32_t ty=((i&1)<<3)+y - viewport.y;
4073 for(int32_t k=0; k<8; k+=2)
4074 for(int32_t j=0; j<8; j+=2)
4075 if((k+j)%4 < 2) rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,color);
4076 }
4077 }
4078 }
4079 }
4080 }
4081 static void put_walkflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4082 {
4083 ALLEGRO_COLOR col_solid = al_map_rgba(178,36,36,info_opacity);
4084 ALLEGRO_COLOR col_water1 = al_map_rgba(85,85,255,info_opacity);
4085 ALLEGRO_COLOR col_lhook = al_map_rgba(170,170,170,info_opacity);
4086 ALLEGRO_COLOR col_stepable = al_map_rgba(165,105,8,info_opacity);
4087 ALLEGRO_COLOR col_dmg = al_map_rgba(255,255,0,info_opacity);
4088 newcombo const &c = combobuf[cmbdat];
4089
4090 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
4091
4092 int32_t xx = x-viewport.x;
4093 int32_t yy = y+playing_field_offset-viewport.y;
4094
4095 int32_t bridgedetected = 0;
4096
4097 // Draw damage combos
4098 bool dmg = combo_class_buf[c.type].modify_hp_amount;
4099
4100 for(int32_t i=0; i<4; i++)
4101 {
4102 int32_t tx=((i&2)<<2)+xx;
4103 int32_t ty=((i&1)<<3)+yy;
4104 int32_t tx2=((i&2)<<2)+x;
4105 int32_t ty2=((i&1)<<3)+y;
4106 for (int32_t m = lyr-1; m <= 1; m++)
4107 {
4108 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4109 {
4110 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && !_walkflag_layer(tx2, ty2, m))
4111 {
4112 bridgedetected |= (1<<i);
4113 }
4114 }
4115 else
4116 {
4117 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && _effectflag_layer(tx2, ty2, m))
4118 {
4119 bridgedetected |= (1<<i);
4120 }
4121 }
4122 }
4123 if ((bridgedetected & (1<<i)))
4124 continue;
4125 bool doladdercheck = true;
4126
4127 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4128 {
4129 for(int32_t k=0; k<8; k+=2)
4130 for(int32_t j=0; j<8; j+=2)
4131 if(((k+j)/2)%2)
4132 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_water1);
4133 }
4134 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4135 {
4136 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4137 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4138 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_water1);
4139 else al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_lhook);
4140 }
4141
4142 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4143 {
4144 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4145 {
4146 for(int32_t k=0; k<8; k+=2)
4147 for(int32_t j=0; j<8; j+=2)
4148 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,((k+j)/2)%2 ? col_stepable : col_lhook);
4149 }
4150 else
4151 {
4152 ALLEGRO_COLOR* color = &col_solid;
4153
4154 if(isstepable(cmbdat)&& (!doladdercheck))
4155 color=&col_stepable;
4156 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4157 color=&col_lhook;
4158
4159 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,*color);
4160 }
4161 }
4162
4163 if(dmg)
4164 {
4165 for(int32_t k=0; k<8; k+=2)
4166 for(int32_t j=0; j<8; j+=2)
4167 if((k+j)%4 < 2) al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_dmg);
4168 }
4169 }
4170 }
4171
4172 void put_effectflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
4173 {
4174 newcombo const &c = combobuf[cmbdat];
4175
4176 int32_t xx = x-xofs-viewport.x;
4177 int32_t yy = y+playing_field_offset-yofs-viewport.y;
4178
4179 for(int32_t i=0; i<4; i++)
4180 {
4181 int32_t tx=((i&2)<<2)+xx;
4182 int32_t ty=((i&1)<<3)+yy;
4183
4184 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4185 {
4186 int32_t color = vc(10);
4187
4188 rectfill(dest,tx,ty,tx+7,ty+7,color);
4189 }
4190 }
4191 }
4192 static void put_effectflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4193 {
4194 ALLEGRO_COLOR col_eff = al_map_rgba(85,255,85,info_opacity);
4195 newcombo const &c = combobuf[cmbdat];
4196
4197 int32_t xx = x-viewport.x;
4198 int32_t yy = y+playing_field_offset-viewport.y;
4199
4200 for(int32_t i=0; i<4; i++)
4201 {
4202 int32_t tx=((i&2)<<2)+xx;
4203 int32_t ty=((i&1)<<3)+yy;
4204
4205 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4206 {
4207 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_eff);
4208 }
4209 }
4210 }
4211
4212 void draw_ladder_platform(BITMAP* dest, int32_t x, int32_t y, int32_t c)
4213 {
4214 for(auto cx = 0; cx < 256; cx += 16)
4215 {
4216 for(auto cy = 0; cy < 176; cy += 16)
4217 {
4218 if(isSVLadder(cx,cy))
4219 {
4220 auto nx = cx+x, ny = cy+y;
4221 if(cy && !isSVLadder(cx,cy-16))
4222 line(dest,nx,ny,nx+15,ny,c);
4223 rectfill(dest,nx,ny,nx+3,ny+15,c);
4224 rectfill(dest,nx+12,ny,nx+15,ny+15,c);
4225 rectfill(dest,nx+4,ny+2,nx+11,ny+5,c);
4226 rectfill(dest,nx+4,ny+10,nx+11,ny+13,c);
4227 }
4228 else if(isSVPlatform(cx,cy))
4229 {
4230 line(dest,cx+x,cy+y,cx+x+15,cy+y,c);
4231 }
4232 }
4233 }
4234 }
4235 void draw_ladder_platform_a5(int32_t x, int32_t y, ALLEGRO_COLOR c)
4236 {
4237 for(auto cx = 0; cx < 256; cx += 16)
4238 {
4239 for(auto cy = 0; cy < 176; cy += 16)
4240 {
4241 if(isSVLadder(cx,cy))
4242 {
4243 auto nx = cx+x, ny = cy+y;
4244 if(cy && !isSVLadder(cx,cy-16))
4245 al_draw_line(nx,ny,nx+15,ny,c,1);
4246 al_draw_filled_rectangle(nx,ny,nx+4,ny+16,c);
4247 al_draw_filled_rectangle(nx+12,ny,nx+16,ny+16,c);
4248 al_draw_filled_rectangle(nx+4,ny+2,nx+12,ny+6,c);
4249 al_draw_filled_rectangle(nx+4,ny+10,nx+12,ny+14,c);
4250 }
4251 else if(isSVPlatform(cx,cy))
4252 {
4253 al_draw_line(cx+x,cy+y,cx+x+15,cy+y,c,1);
4254 }
4255 }
4256 }
4257 }
4258
4259 // Walkflags L4 cheat
4260 void do_walkflags(const screen_handles_t& screen_handles, int32_t x, int32_t y)
4261 {
4262 if (!show_walkflags)
4263 return;
4264
4265 start_info_bmp();
4266
4267 mapscr* scr = screen_handles[0].scr;
4268 for(int32_t i=0; i<176; i++)
4269 {
4270 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4271 }
4272
4273 for(int32_t k=0; k<2; k++)
4274 {
4275 scr = screen_handles[k + 1].scr;
4276
4277 if (scr)
4278 {
4279 for(int32_t i=0; i<176; i++)
4280 {
4281 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], k%2+1);
4282 }
4283 }
4284 }
4285
4286 end_info_bmp();
4287 }
4288
4289 void do_walkflags(int32_t x, int32_t y)
4290 {
4291 if (!show_walkflags)
4292 return;
4293
4294 x += -viewport.x;
4295 y += playing_field_offset - viewport.y;
4296
4297 start_info_bmp();
4298
4299 draw_ladder_platform_a5(x,y,al_map_rgba(165,105,8,info_opacity));
4300 draw_solid_objects_a5(x,y,al_map_rgba(178,36,36,info_opacity));
4301 draw_slopes_a5(x,y,al_map_rgba(255,85,255,info_opacity));
4302
4303 end_info_bmp();
4304 }
4305
4306 // Effectflags L4 cheat
4307 void do_effectflags(mapscr* scr, int32_t x, int32_t y)
4308 {
4309 if(show_effectflags)
4310 {
4311 start_info_bmp();
4312
4313 for(int32_t i=0; i<176; i++)
4314 {
4315 put_effectflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4316 }
4317
4318 end_info_bmp();
4319 }
4320 }
4321
4322 272141 void calc_darkroom_combos(mapscr* scr, int offx, int offy)
4323 {
4324 272141 int map = scr->map;
4325 272141 int screen = scr->screen;
4326
4327
2/2
✓ Branch 0 taken 1904987 times.
✓ Branch 1 taken 272141 times.
2177128 for(int32_t lyr = 0; lyr < 7; ++lyr)
4328 {
4329 1904987 mapscr* scr = get_scr_layer(map, screen, lyr);
4330
2/2
✓ Branch 0 taken 780869 times.
✓ Branch 1 taken 1124118 times.
1904987 if (!scr->is_valid()) continue;
4331
4332
2/2
✓ Branch 0 taken 137432944 times.
✓ Branch 1 taken 780869 times.
138213813 for(int32_t q = 0; q < 176; ++q)
4333 {
4334 137432944 newcombo const& cmb = combobuf[scr->data[q]];
4335
2/2
✓ Branch 0 taken 136828325 times.
✓ Branch 1 taken 604619 times.
137432944 if(cmb.type == cTORCH)
4336 {
4337 604619 do_torch_combo(cmb, COMBOX(q)+8+offx, COMBOY(q)+8+offy, darkscr_bmp);
4338 604619 }
4339 137432944 }
4340 780869 }
4341 272141 }
4342
4343 272141 void calc_darkroom_ffcs(mapscr* scr, int offx, int offy)
4344 {
4345 272141 word c = scr->numFFC();
4346
2/2
✓ Branch 0 taken 537406 times.
✓ Branch 1 taken 272141 times.
809547 for(int q = 0; q < c; ++q)
4347 {
4348 537406 newcombo const& cmb = combobuf[scr->ffcs[q].data];
4349
2/2
✓ Branch 0 taken 522598 times.
✓ Branch 1 taken 14808 times.
537406 if(cmb.type == cTORCH)
4350 {
4351 14808 int cx = scr->ffcs[q].x.getInt()+(scr->ffEffectWidth(q)/2)+offx;
4352 14808 int cy = (scr->ffcs[q].y.getInt())+(scr->ffEffectHeight(q)/2)+offy;
4353 14808 do_torch_combo(cmb, cx, cy, darkscr_bmp);
4354 14808 }
4355 537406 }
4356 272141 }
4357
4358 struct nearby_screen_t
4359 {
4360 int screen;
4361 int offx;
4362 int offy;
4363 screen_handles_t screen_handles;
4364 };
4365 typedef std::vector<nearby_screen_t> nearby_screens_t;
4366
4367 15487811 static nearby_screens_t get_nearby_screens_non_scrolling_region()
4368 {
4369 15487811 nearby_screens_t nearby_screens;
4370
4371 15487811 mapscr* base_scr = origin_scr;
4372
1/2
✓ Branch 0 taken 15487811 times.
✗ Branch 1 not taken.
15487811 auto& nearby_screen = nearby_screens.emplace_back();
4373 15487811 nearby_screen.screen = cur_screen;
4374
1/2
✓ Branch 0 taken 15487811 times.
✗ Branch 1 not taken.
15487811 nearby_screen.screen_handles = create_screen_handles(base_scr);
4375
4376 15487811 return nearby_screens;
4377
1/2
✓ Branch 0 taken 15487811 times.
✗ Branch 1 not taken.
15487811 }
4378
4379 48296 static nearby_screens_t get_nearby_screens_scrolling_region()
4380 {
4381 48296 nearby_screens_t nearby_screens;
4382
4383
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x0 = viewport.left() / 256;
4384
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x1 = (viewport.right() - 1) / 256;
4385
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y0 = viewport.top() / 176;
4386
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y1 = (viewport.bottom() - 1) / 176;
4387
4388
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x0 = std::clamp(screens_x0, 0, 15);
4389
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x1 = std::clamp(screens_x1, 0, 15);
4390
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y0 = std::clamp(screens_y0, 0, 8);
4391
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y1 = std::clamp(screens_y1, 0, 8);
4392
4393
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 79928 times.
128224 for (int x = screens_x0; x <= screens_x1; x++)
4394 {
4395
2/2
✓ Branch 0 taken 169672 times.
✓ Branch 1 taken 79928 times.
249600 for (int y = screens_y0; y <= screens_y1; y++)
4396 {
4397 169672 int screen = cur_screen + x + y*16;
4398
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!is_in_current_region(screen)) continue;
4399
4400
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 mapscr* base_scr = get_scr(screen);
4401
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!base_scr->is_valid()) continue;
4402
4403
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
4404
4405
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto& nearby_screen = nearby_screens.emplace_back();
4406 169672 nearby_screen.screen = screen;
4407 169672 nearby_screen.offx = offx;
4408 169672 nearby_screen.offy = offy;
4409
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 nearby_screen.screen_handles = create_screen_handles(base_scr);
4410 169672 }
4411 79928 }
4412
4413 48296 return nearby_screens;
4414
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 }
4415
4416 3658 static nearby_screens_t get_nearby_screens_smooth_maze()
4417 {
4418 3658 nearby_screens_t nearby_screens;
4419
4420
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x0 = viewport.left() / 256;
4421
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x1 = (viewport.right() - 1) / 256;
4422
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y0 = viewport.top() / 176;
4423
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y1 = (viewport.bottom() - 1) / 176;
4424
4425
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.left() < 0) screens_x0--;
4426
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.top() < 0) screens_y0--;
4427
4428
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 7308 times.
10966 for (int x = screens_x0; x <= screens_x1; x++)
4429 {
4430
2/2
✓ Branch 0 taken 18600 times.
✓ Branch 1 taken 7308 times.
25908 for (int y = screens_y0; y <= screens_y1; y++)
4431 {
4432 18600 int screen = -1;
4433 mapscr* base_scr;
4434 int offx, offy;
4435
4436 18600 mapscr* maze_scr = maze_state.scr;
4437 18600 int maze_screen = maze_scr->screen;
4438
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_x = get_region_relative_dx(maze_screen);
4439
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_y = get_region_relative_dy(maze_screen);
4440 18600 int maze_screen_dx = x - maze_screen_x;
4441 18600 int maze_screen_dy = y - maze_screen_y;
4442 18600 int exitdir = maze_scr->exitdir;
4443
4444 bool should_draw_maze_screen;
4445
2/2
✓ Branch 0 taken 9052 times.
✓ Branch 1 taken 9548 times.
18600 if (maze_state.lost)
4446 {
4447 9548 should_draw_maze_screen = true;
4448 9548 }
4449 else
4450 {
4451 9052 should_draw_maze_screen = true;
4452
4/6
✓ Branch 0 taken 9052 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6844 times.
✓ Branch 3 taken 2208 times.
✓ Branch 4 taken 6844 times.
✗ Branch 5 not taken.
9052 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != exitdir && XY_DELTA_TO_DIR(0, maze_screen_dy) != exitdir;
4453
2/2
✓ Branch 0 taken 3850 times.
✓ Branch 1 taken 5202 times.
9052 if (maze_state.enter_dir != dir_invalid)
4454
4/6
✓ Branch 0 taken 3850 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3304 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 3304 times.
✗ Branch 5 not taken.
3850 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != maze_state.enter_dir && XY_DELTA_TO_DIR(0, maze_screen_dy) != maze_state.enter_dir;
4455 }
4456
4457
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (should_draw_maze_screen)
4458 {
4459 16048 screen = maze_state.scr->screen;
4460 16048 base_scr = maze_state.scr;
4461
1/2
✓ Branch 0 taken 16048 times.
✗ Branch 1 not taken.
16048 std::tie(offx, offy) = translate_screen_coordinates_to_world(cur_screen + x + y*16);
4462 16048 }
4463
4464
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (screen == -1)
4465 {
4466 2552 screen = cur_screen + x + y*16;
4467
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!is_in_current_region(screen)) continue;
4468
4469
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 base_scr = get_scr(screen);
4470
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!base_scr->is_valid()) continue;
4471
4472
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 std::tie(offx, offy) = translate_screen_coordinates_to_world(screen);
4473 2552 }
4474
4475
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 auto& nearby_screen = nearby_screens.emplace_back();
4476 18600 nearby_screen.screen = screen;
4477 18600 nearby_screen.offx = offx;
4478 18600 nearby_screen.offy = offy;
4479
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 nearby_screen.screen_handles = create_screen_handles(base_scr);
4480 18600 }
4481 7308 }
4482
4483 3658 return nearby_screens;
4484
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 }
4485
4486 15539765 static nearby_screens_t get_nearby_screens()
4487 {
4488
4/4
✓ Branch 0 taken 9214 times.
✓ Branch 1 taken 15530551 times.
✓ Branch 2 taken 3658 times.
✓ Branch 3 taken 5556 times.
15539765 if (maze_state.active && maze_state.loopy)
4489 3658 return get_nearby_screens_smooth_maze();
4490
4491
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 15487811 times.
15536107 if (is_in_scrolling_region())
4492 48296 return get_nearby_screens_scrolling_region();
4493
4494 15487811 return get_nearby_screens_non_scrolling_region();
4495 15539765 }
4496
4497 202038438 static void for_every_nearby_screen(const nearby_screens_t& nearby_screens, const std::function <void (screen_handles_t, int, int, int)>& fn)
4498 {
4499
2/2
✓ Branch 0 taken 203823040 times.
✓ Branch 1 taken 202038438 times.
405861478 for (auto& nearby_screen : nearby_screens)
4500 203823040 fn(nearby_screen.screen_handles, nearby_screen.screen, nearby_screen.offx, nearby_screen.offy);
4501 202038438 }
4502
4503 124318120 static void draw_msgstr(byte layer, BITMAP* dest = nullptr)
4504 {
4505
2/2
✓ Branch 0 taken 15539765 times.
✓ Branch 1 taken 108778355 times.
124318120 if(layer != msgstr_layer) return;
4506
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 if(!dest) dest = framebuf;
4507
4508
2/2
✓ Branch 0 taken 679438 times.
✓ Branch 1 taken 14860327 times.
15539765 if(!(msg_bg_display_buf->clip))
4509 {
4510 679438 blit_msgstr_bg(dest,0,0,0,playing_field_offset,256,176);
4511 679438 }
4512
4513
2/2
✓ Branch 0 taken 679438 times.
✓ Branch 1 taken 14860327 times.
15539765 if(!(msg_portrait_display_buf->clip))
4514 {
4515 679438 blit_msgstr_prt(dest,0,0,0,playing_field_offset,256,176);
4516 679438 }
4517
4518
2/2
✓ Branch 0 taken 692845 times.
✓ Branch 1 taken 14846920 times.
15539765 if(!(msg_txt_display_buf->clip))
4519 {
4520 692845 blit_msgstr_fg(dest,0,0,0,playing_field_offset,256,176);
4521 692845 }
4522 124318120 }
4523
4524 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y);
4525
4526 62159060 static void set_draw_screen_clip(BITMAP* bmp)
4527 {
4528 62159060 set_clip_rect(bmp, draw_screen_clip_rect_x1, draw_screen_clip_rect_y1, draw_screen_clip_rect_x2, draw_screen_clip_rect_y2);
4529 62159060 }
4530
4531 46119039 void draw_screen(bool showhero, bool runGeneric)
4532 {
4533 46119039 clear_info_bmp();
4534
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46119039 times.
46119039 if((GameFlags & (GAMEFLAG_SCRIPTMENU_ACTIVE|GAMEFLAG_F6SCRIPT_ACTIVE))!=0)
4535 {
4536 FFCore.doScriptMenuDraws();
4537 return;
4538 }
4539
4540
2/2
✓ Branch 0 taken 31180939 times.
✓ Branch 1 taken 14938100 times.
46119039 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_PRE_DRAW);
4541
4542 46119039 clear_bitmap(framebuf);
4543 46119039 clear_clip_rect(framebuf);
4544
4545 46119039 int32_t cmby2=0;
4546
4547 // Draw some background layers
4548 46119039 clear_bitmap(scrollbuf);
4549
4550 46119039 auto nearby_screens = get_nearby_screens();
4551
4552 // Handle layer 2/3 possibly being background layers.
4553
1/2
✓ Branch 0 taken 46119039 times.
✗ Branch 1 not taken.
61795122 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4554 15676083 mapscr* base_scr = screen_handles[0].base_scr;
4555
2/2
✓ Branch 0 taken 15548802 times.
✓ Branch 1 taken 127281 times.
15676083 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4556 127281 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4557 15676083 });
4558
4559
2/2
✓ Branch 0 taken 127281 times.
✓ Branch 1 taken 45991758 times.
46119039 if (XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4560 {
4561
1/2
✓ Branch 0 taken 127281 times.
✗ Branch 1 not taken.
127281 do_layer_primitives(scrollbuf, 2);
4562
1/2
✓ Branch 0 taken 127281 times.
✗ Branch 1 not taken.
127281 particles.draw(scrollbuf, true, 2);
4563 127281 }
4564
2/2
✓ Branch 0 taken 15539765 times.
✓ Branch 1 taken 30579274 times.
46119039 _do_current_ffc_layer(scrollbuf, -2);
4565
2/2
✓ Branch 0 taken 127281 times.
✓ Branch 1 taken 15412484 times.
15539765 if (XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4566
1/2
✓ Branch 0 taken 127281 times.
✗ Branch 1 not taken.
127281 draw_msgstr(2, scrollbuf);
4567
4568
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4569 15676083 mapscr* base_scr = screen_handles[0].base_scr;
4570
2/2
✓ Branch 0 taken 15583424 times.
✓ Branch 1 taken 92659 times.
15676083 if (XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4571 92659 do_layer(scrollbuf, 0, screen_handles[3], offx, offy);
4572 15676083 });
4573
4574
2/2
✓ Branch 0 taken 92659 times.
✓ Branch 1 taken 15447106 times.
15539765 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4575 {
4576
1/2
✓ Branch 0 taken 92659 times.
✗ Branch 1 not taken.
92659 do_layer_primitives(scrollbuf, 3);
4577
1/2
✓ Branch 0 taken 92659 times.
✗ Branch 1 not taken.
92659 particles.draw(scrollbuf, true, 3);
4578 92659 }
4579
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(scrollbuf, -3);
4580
2/2
✓ Branch 0 taken 92659 times.
✓ Branch 1 taken 15447106 times.
15539765 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4581
1/2
✓ Branch 0 taken 92659 times.
✗ Branch 1 not taken.
92659 draw_msgstr(3, scrollbuf);
4582
4583 // Draw the main combo screens ("layer 0").
4584
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4585 15676083 mapscr* base_scr = screen_handles[0].base_scr;
4586
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15676083 times.
15676083 if (lenscheck(base_scr, 0))
4587 {
4588 15676083 putscr(base_scr, scrollbuf, offx, offy + playing_field_offset);
4589 15676083 }
4590 15676083 });
4591
4592
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539765 times.
15539765 if (lenscheck(hero_scr, 0))
4593 {
4594
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 15073716 times.
15539765 if(!get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4595
3/4
✓ Branch 0 taken 466049 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4136 times.
✓ Branch 3 taken 461913 times.
470185 if(mblock2.draw(scrollbuf,0))
4596
1/2
✓ Branch 0 taken 4136 times.
✗ Branch 1 not taken.
4136 do_primitives(scrollbuf, SPLAYER_MOVINGBLOCK);
4597 15539765 }
4598
4599 // Lens hints, then primitives, then particles.
4600
6/10
✓ Branch 0 taken 15529736 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 15529736 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15529736 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 5876 times.
✓ Branch 9 taken 4153 times.
15539765 if((lensclk || (get_debug() && zc_getkey(KEY_L))) && !get_qr(qr_OLDLENSORDER))
4601 {
4602
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 draw_lens_under(scrollbuf, false);
4603
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4604 5876 }
4605
4606
2/4
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15539765 times.
✗ Branch 3 not taken.
15539765 if(show_layers[0] && lenscheck(hero_scr,0))
4607
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(scrollbuf, 0);
4608
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 particles.draw(scrollbuf, true, 0);
4609
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(scrollbuf, 0);
4610
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(0, scrollbuf);
4611
4612
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_draw_screen_clip(scrollbuf);
4613
4614
2/2
✓ Branch 0 taken 15196506 times.
✓ Branch 1 taken 343259 times.
15539765 if(!(get_qr(qr_LAYER12UNDERCAVE)))
4615 {
4616
4/4
✓ Branch 0 taken 15194632 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 15106248 times.
30356386 if(showhero &&
4617
4/6
✓ Branch 0 taken 15194632 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15159880 times.
✓ Branch 3 taken 34752 times.
✓ Branch 4 taken 15159880 times.
✗ Branch 5 not taken.
15194632 ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom)))
4618 {
4619
3/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 34752 times.
88384 if(Hero.getAction()==climbcovertop)
4620 {
4621 34752 cmby2=16;
4622 34752 }
4623
2/4
✓ Branch 0 taken 53632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53632 times.
53632 else if(Hero.getAction()==climbcoverbottom)
4624 {
4625 53632 cmby2=-16;
4626 53632 }
4627
4628
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw2(scrollbuf,true);
4629
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 Hero.draw(scrollbuf);
4630
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw(scrollbuf,true);
4631
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccx = (int32_t)Hero.getClimbCoverX();
4632
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccy = (int32_t)Hero.getClimbCoverY();
4633
4634
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4635
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4636
4637
4/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✓ Branch 5 taken 73152 times.
88384 if(int32_t(Hero.getX())&15)
4638 {
4639
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4640
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4641 15232 }
4642 88384 }
4643 15196506 }
4644
4645
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4646 15676083 do_layer(scrollbuf, 0, screen_handles[1], offx, offy); // LAYER 1
4647 15676083 });
4648
4649
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_layer_primitives(scrollbuf, 1);
4650
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 particles.draw(scrollbuf, true, 1);
4651
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(scrollbuf, 1);
4652
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(1, scrollbuf);
4653
4654 // Handle layer 2 NOT being used as background layers.
4655
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4656 15676083 mapscr* base_scr = screen_handles[0].base_scr;
4657
2/2
✓ Branch 0 taken 127281 times.
✓ Branch 1 taken 15548802 times.
15676083 if (!XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4658 15548802 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4659 15676083 });
4660
4661
2/2
✓ Branch 0 taken 15412484 times.
✓ Branch 1 taken 127281 times.
15539765 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4662 {
4663
1/2
✓ Branch 0 taken 15412484 times.
✗ Branch 1 not taken.
15412484 do_layer_primitives(scrollbuf, 2);
4664
1/2
✓ Branch 0 taken 15412484 times.
✗ Branch 1 not taken.
15412484 particles.draw(scrollbuf, true, 2);
4665 15412484 }
4666
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(scrollbuf, 2);
4667
2/2
✓ Branch 0 taken 15412484 times.
✓ Branch 1 taken 127281 times.
15539765 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4668
1/2
✓ Branch 0 taken 15412484 times.
✗ Branch 1 not taken.
15412484 draw_msgstr(2, scrollbuf);
4669
4670
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(scrollbuf, SPLAYER_FFC_DRAW);
4671
4672
2/2
✓ Branch 0 taken 343259 times.
✓ Branch 1 taken 15196506 times.
15539765 if(get_qr(qr_LAYER12UNDERCAVE))
4673 {
4674
2/4
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 343259 times.
686518 if(showhero &&
4675
3/6
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 343259 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 343259 times.
✗ Branch 5 not taken.
343259 ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom)))
4676 {
4677 if(Hero.getAction()==climbcovertop)
4678 {
4679 cmby2=16;
4680 }
4681 else if(Hero.getAction()==climbcoverbottom)
4682 {
4683 cmby2=-16;
4684 }
4685
4686 decorations.draw2(scrollbuf,true);
4687 Hero.draw(scrollbuf);
4688 decorations.draw(scrollbuf,true);
4689 int32_t ccx = (int32_t)(Hero.getClimbCoverX());
4690 int32_t ccy = (int32_t)(Hero.getClimbCoverY());
4691
4692 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4693 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4694
4695 if(int32_t(Hero.getX())&15)
4696 {
4697 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4698 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4699 }
4700 }
4701 343259 }
4702
4703
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 15073716 times.
15539765 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4704 {
4705
1/2
✓ Branch 0 taken 15073716 times.
✗ Branch 1 not taken.
30283750 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4706 15210034 do_layer(scrollbuf, -2, screen_handles[0], offx, offy); // push blocks!
4707
2/2
✓ Branch 0 taken 14478915 times.
✓ Branch 1 taken 731119 times.
15210034 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
4708 {
4709 731119 do_layer(scrollbuf, -2, screen_handles[1], offx, offy); // push blocks!
4710 731119 do_layer(scrollbuf, -2, screen_handles[2], offx, offy); // push blocks!
4711 731119 }
4712 15210034 });
4713
4714
1/2
✓ Branch 0 taken 15073716 times.
✗ Branch 1 not taken.
15073716 do_primitives(scrollbuf, SPLAYER_PUSHBLOCK);
4715 15073716 }
4716
4717 // Show walkflags cheat
4718
2/4
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15539765 times.
15539765 if (show_walkflags || show_effectflags)
4719 {
4720 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4721 do_walkflags(screen_handles, offx, offy);
4722 do_effectflags(screen_handles[0].base_scr, offx, offy);
4723 });
4724
4725 do_walkflags(0, 0);
4726 }
4727
4728
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 putscrdoors(nearby_screens, scrollbuf, 0, playing_field_offset);
4729
4730 // Lens hints, doors etc.
4731
4/8
✓ Branch 0 taken 15529736 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 15529736 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15529736 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
15539765 if(lensclk || (get_debug() && zc_getkey(KEY_L)))
4732 {
4733
2/2
✓ Branch 0 taken 4153 times.
✓ Branch 1 taken 5876 times.
10029 if(get_qr(qr_OLDLENSORDER))
4734 {
4735
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 draw_lens_under(scrollbuf, false);
4736
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4737 4153 }
4738
4739
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 draw_lens_under(scrollbuf, true);
4740
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_2);
4741 10029 }
4742
4743 // Blit those layers onto framebuf
4744
4745
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_draw_screen_clip(framebuf);
4746
4747
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 blit(scrollbuf, framebuf, 0, 0, 0, 0, 256, 232);
4748
4749 // After this point, scrollbuf is no longer drawn to - so things like dosubscr have access to a "partially rendered" frame.
4750 // I think only used for COOLSCROLL==0? Seems like a silly feature...
4751
4752 // Draw the subscreen, without clipping
4753
2/2
✓ Branch 0 taken 9251384 times.
✓ Branch 1 taken 6288381 times.
15539765 if(!get_qr(qr_SUBSCREENOVERSPRITES))
4754 {
4755 9251384 bool dotime = false;
4756
4/6
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3412853 times.
✓ Branch 3 taken 5838531 times.
✓ Branch 4 taken 3412853 times.
✗ Branch 5 not taken.
9251384 if (replay_version_check(22)) dotime = game->should_show_time();
4757
1/2
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
9251384 put_passive_subscr(framebuf, 0, 0, dotime, sspUP);
4758 9251384 }
4759
4760 // Draw some sprites onto framebuf
4761
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_clip_rect(framebuf,0,0,256,232);
4762
4763
2/2
✓ Branch 0 taken 99496 times.
✓ Branch 1 taken 15440269 times.
15539765 if(!(pricesdisplaybuf->clip))
4764 {
4765
1/2
✓ Branch 0 taken 99496 times.
✗ Branch 1 not taken.
99496 masked_blit(pricesdisplaybuf,framebuf,0,0,0,playing_field_offset,256,176);
4766 99496 }
4767
4768
5/6
✓ Branch 0 taken 15494139 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15487811 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15539765 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4769 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4770
4771
8/10
✓ Branch 0 taken 15537891 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 15537891 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15503139 times.
✓ Branch 5 taken 34752 times.
✓ Branch 6 taken 15503139 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15449507 times.
✓ Branch 9 taken 53632 times.
15539765 if(showhero && ((Hero.getAction()!=climbcovertop)&&(Hero.getAction()!=climbcoverbottom)))
4772 {
4773
1/2
✓ Branch 0 taken 15449507 times.
✗ Branch 1 not taken.
15449507 Hero.draw_under(framebuf);
4774
4775
3/4
✓ Branch 0 taken 15449507 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 141385 times.
✓ Branch 3 taken 15308122 times.
15449507 if(Hero.isSwimming())
4776 {
4777
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw2(framebuf,true);
4778
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 Hero.draw(framebuf);
4779
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw(framebuf,true);
4780 141385 }
4781 15449507 }
4782
4783
2/2
✓ Branch 0 taken 26095 times.
✓ Branch 1 taken 15513670 times.
15539765 if(drawguys)
4784 {
4785
4/4
✓ Branch 0 taken 1982674 times.
✓ Branch 1 taken 13530996 times.
✓ Branch 2 taken 991089 times.
✓ Branch 3 taken 991585 times.
15513670 if(get_qr(qr_NOFLICKER) || (frame&1))
4786 {
4787 // Just clips sprites if in a repeating, smooth maze.
4788
2/2
✓ Branch 0 taken 14512871 times.
✓ Branch 1 taken 9214 times.
14522085 bool do_clip = maze_state.active && maze_state.loopy;
4789
4790
3/4
✓ Branch 0 taken 23627227 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9105142 times.
✓ Branch 3 taken 14522085 times.
23627227 for(int32_t i=0; i<Ewpns.Count(); i++)
4791 {
4792
3/4
✓ Branch 0 taken 9105142 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197943 times.
✓ Branch 3 taken 8907199 times.
9105142 if(((weapon *)Ewpns.spr(i))->behind)
4793
2/4
✓ Branch 0 taken 197943 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197943 times.
✗ Branch 3 not taken.
197943 Ewpns.spr(i)->draw(framebuf);
4794 9105142 }
4795
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_EWEAP_BEHIND_DRAW);
4796
4797
3/4
✓ Branch 0 taken 19197181 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4675096 times.
✓ Branch 3 taken 14522085 times.
19197181 for(int32_t i=0; i<Lwpns.Count(); i++)
4798 {
4799
3/4
✓ Branch 0 taken 4675096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3205 times.
✓ Branch 3 taken 4671891 times.
4675096 if(((weapon *)Lwpns.spr(i))->behind)
4800
2/4
✓ Branch 0 taken 3205 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3205 times.
✗ Branch 3 not taken.
3205 Lwpns.spr(i)->draw(framebuf);
4801 4675096 }
4802
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_LWEAP_BEHIND_DRAW);
4803
4804
6/6
✓ Branch 0 taken 9785221 times.
✓ Branch 1 taken 4736864 times.
✓ Branch 2 taken 1348300 times.
✓ Branch 3 taken 8436921 times.
✓ Branch 4 taken 674011 times.
✓ Branch 5 taken 674289 times.
14522085 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4805 {
4806
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 9107274 times.
9110932 if (do_clip)
4807
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.drawshadow_smooth_maze(framebuf,get_qr(qr_TRANSSHADOWS)!=0);
4808 else
4809
1/2
✓ Branch 0 taken 9107274 times.
✗ Branch 1 not taken.
9107274 guys.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0,true);
4810 9110932 }
4811
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4812
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.draw_smooth_maze(framebuf);
4813 else
4814
1/2
✓ Branch 0 taken 14518427 times.
✗ Branch 1 not taken.
14518427 guys.draw(framebuf,true);
4815
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4816 {
4817 3658 int maze_screen = maze_state.scr->screen;
4818
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4819
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(framebuf, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4820 3658 }
4821
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_NPC_DRAW);
4822
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4823
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(framebuf);
4824
4825
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 chainlinks.draw(framebuf,true);
4826
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4827 //Lwpns.draw(framebuf,true);
4828
4829
3/4
✓ Branch 0 taken 23627227 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9105142 times.
✓ Branch 3 taken 14522085 times.
23627227 for(int32_t i=0; i<Ewpns.Count(); i++)
4830 {
4831
3/4
✓ Branch 0 taken 9105142 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8907199 times.
✓ Branch 3 taken 197943 times.
9105142 if(!((weapon *)Ewpns.spr(i))->behind)
4832
2/4
✓ Branch 0 taken 8907199 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8907199 times.
✗ Branch 3 not taken.
8907199 Ewpns.spr(i)->draw(framebuf);
4833 9105142 }
4834
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_EWEAP_FRONT_DRAW);
4835
4836
3/4
✓ Branch 0 taken 19197181 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4675096 times.
✓ Branch 3 taken 14522085 times.
19197181 for(int32_t i=0; i<Lwpns.Count(); i++)
4837 {
4838
3/4
✓ Branch 0 taken 4675096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4671891 times.
✓ Branch 3 taken 3205 times.
4675096 if(!((weapon *)Lwpns.spr(i))->behind)
4839
2/4
✓ Branch 0 taken 4671891 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4671891 times.
✗ Branch 3 not taken.
4671891 Lwpns.spr(i)->draw(framebuf);
4840 4675096 }
4841
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_LWEAP_FRONT_DRAW);
4842
4843
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4844
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 items.draw_smooth_maze(framebuf);
4845 else
4846
1/2
✓ Branch 0 taken 14518427 times.
✗ Branch 1 not taken.
14518427 items.draw(framebuf,true);
4847
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4848 {
4849 3658 int maze_screen = maze_state.scr->screen;
4850
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4851
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(framebuf, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4852 3658 }
4853
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_ITEMSPRITE_DRAW);
4854
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4855
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(framebuf);
4856 14522085 }
4857 else
4858 {
4859
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
4860 {
4861
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✓ Branch 3 taken 496727 times.
505372 if(((weapon *)Ewpns.spr(i))->behind)
4862
2/4
✓ Branch 0 taken 8645 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✗ Branch 3 not taken.
8645 Ewpns.spr(i)->draw(framebuf);
4863 505372 }
4864
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_EWEAP_BEHIND_DRAW);
4865
4866
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
4867 {
4868
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 231146 times.
231146 if(((weapon *)Lwpns.spr(i))->behind)
4869 Lwpns.spr(i)->draw(framebuf);
4870 231146 }
4871
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_LWEAP_BEHIND_DRAW);
4872
4873
3/4
✓ Branch 0 taken 228620 times.
✓ Branch 1 taken 762965 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228620 times.
991585 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4874 {
4875
1/2
✓ Branch 0 taken 228620 times.
✗ Branch 1 not taken.
228620 guys.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0,true);
4876 228620 }
4877
4878
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 items.draw(framebuf,false);
4879
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_ITEMSPRITE_DRAW);
4880
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 chainlinks.draw(framebuf,false);
4881
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4882 //Lwpns.draw(framebuf,false);
4883
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 guys.draw(framebuf,false);
4884
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_NPC_DRAW);
4885
4886
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
4887 {
4888
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✓ Branch 3 taken 8645 times.
505372 if(!((weapon *)Ewpns.spr(i))->behind)
4889 {
4890
2/4
✓ Branch 0 taken 496727 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✗ Branch 3 not taken.
496727 Ewpns.spr(i)->draw(framebuf);
4891 496727 }
4892 505372 }
4893
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_EWEAP_FRONT_DRAW);
4894
4895
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
4896 {
4897
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 if(!((weapon *)Lwpns.spr(i))->behind)
4898 {
4899
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 Lwpns.spr(i)->draw(framebuf);
4900 231146 }
4901 231146 }
4902
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_LWEAP_FRONT_DRAW);
4903 }
4904
4905
1/2
✓ Branch 0 taken 15513670 times.
✗ Branch 1 not taken.
15513670 guys.draw2(framebuf,true);
4906 15513670 }
4907
4908
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539765 times.
15539765 if(mirror_portal.destdmap > -1)
4909 mirror_portal.draw(framebuf);
4910
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 portals.draw(framebuf,true);
4911
4912
8/10
✓ Branch 0 taken 15537891 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 15537891 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15503139 times.
✓ Branch 5 taken 34752 times.
✓ Branch 6 taken 15503139 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15449507 times.
✓ Branch 9 taken 53632 times.
15539765 if(showhero && ((Hero.getAction()!=climbcovertop)&& (Hero.getAction()!=climbcoverbottom)))
4913 {
4914
2/2
✓ Branch 0 taken 14989874 times.
✓ Branch 1 taken 459633 times.
15449507 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4915 {
4916
1/2
✓ Branch 0 taken 14989874 times.
✗ Branch 1 not taken.
14989874 mblock2.draw(framebuf,-1);
4917
1/2
✓ Branch 0 taken 14989874 times.
✗ Branch 1 not taken.
14989874 do_primitives(framebuf, SPLAYER_MOVINGBLOCK);
4918 14989874 }
4919
3/4
✓ Branch 0 taken 15449507 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15308122 times.
✓ Branch 3 taken 141385 times.
15449507 if(!Hero.isSwimming())
4920 {
4921
8/12
✓ Branch 0 taken 15308122 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15308122 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15288952 times.
✓ Branch 5 taken 19170 times.
✓ Branch 6 taken 15288952 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15288952 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1370 times.
✓ Branch 11 taken 15306752 times.
15308122 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4922 {
4923
2/2
✓ Branch 0 taken 18485 times.
✓ Branch 1 taken 15289637 times.
15308122 Hero.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0);
4924 18485 }
4925
4926
6/8
✓ Branch 0 taken 15308122 times.
✓ Branch 1 taken 15289637 times.
✓ Branch 2 taken 15308122 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15308122 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15294058 times.
✓ Branch 7 taken 14064 times.
18485 if(Hero.getZ() <= (zfix)zinit.jump_hero_layer_threshold)
4927 {
4928
1/2
✓ Branch 0 taken 15294058 times.
✗ Branch 1 not taken.
15294058 decorations.draw2(framebuf,true);
4929
1/2
✓ Branch 0 taken 15294058 times.
✗ Branch 1 not taken.
15294058 Hero.draw(framebuf);
4930
1/2
✓ Branch 0 taken 15294058 times.
✗ Branch 1 not taken.
15294058 decorations.draw(framebuf,true);
4931 15294058 }
4932 15308122 }
4933 15449507 }
4934
4935
3/4
✓ Branch 0 taken 54880218 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39340453 times.
✓ Branch 3 taken 15539765 times.
54880218 for(int32_t i=0; i<guys.Count(); i++)
4936 {
4937
3/4
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15945464 times.
✓ Branch 3 taken 23394989 times.
39340453 if(((enemy*)guys.spr(i))->family == eeWALK)
4938 {
4939
3/4
✓ Branch 0 taken 15945464 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7295 times.
✓ Branch 3 taken 15938169 times.
15945464 if(((eStalfos*)guys.spr(i))->hashero)
4940 {
4941
2/4
✓ Branch 0 taken 7295 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7295 times.
✗ Branch 3 not taken.
7295 guys.spr(i)->draw(framebuf);
4942 7295 }
4943 15945464 }
4944
4945
3/4
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 507162 times.
✓ Branch 3 taken 38833291 times.
39340453 if(((enemy*)guys.spr(i))->family == eeWALLM)
4946 {
4947
3/4
✓ Branch 0 taken 507162 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✓ Branch 3 taken 505833 times.
507162 if(((eWallM*)guys.spr(i))->hashero)
4948 {
4949
2/4
✓ Branch 0 taken 1329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✗ Branch 3 not taken.
1329 guys.spr(i)->draw(framebuf);
4950 1329 }
4951 507162 }
4952
4953
11/20
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39340453 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 39340453 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 39340453 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 39340453 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 39340453 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 39340453 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 39340453 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 39340453 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1342694 times.
✓ Branch 19 taken 37997759 times.
39340453 if(guys.spr(i)->z+guys.spr(i)->fakez > Hero.getZ()+Hero.getFakeZ())
4954 {
4955 //Jumping enemies in front of Hero.
4956
2/4
✓ Branch 0 taken 1342694 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1342694 times.
✗ Branch 3 not taken.
1342694 guys.spr(i)->draw(framebuf);
4957 1342694 }
4958
1/2
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
39340453 do_primitives(framebuf, SPLAYER_NPC_ABOVEPLAYER_DRAW);
4959 39340453 }
4960
4961 // Draw some layers onto framebuf
4962
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_draw_screen_clip(framebuf);
4963
5/6
✓ Branch 0 taken 15494139 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15487811 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15539765 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4964 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4965
4966 // Handle layer 3 NOT being used as background layers.
4967
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4968 15676083 mapscr* base_scr = screen_handles[0].base_scr;
4969
2/2
✓ Branch 0 taken 92659 times.
✓ Branch 1 taken 15583424 times.
15676083 if (!XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4970 15583424 do_layer(framebuf, 0, screen_handles[3], offx, offy);
4971 15676083 });
4972
4973
2/2
✓ Branch 0 taken 15447106 times.
✓ Branch 1 taken 92659 times.
15539765 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4974 {
4975
1/2
✓ Branch 0 taken 15447106 times.
✗ Branch 1 not taken.
15447106 do_layer_primitives(framebuf, 3);
4976
1/2
✓ Branch 0 taken 15447106 times.
✗ Branch 1 not taken.
15447106 particles.draw(framebuf, true, 3);
4977 15447106 }
4978
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, 3);
4979
2/2
✓ Branch 0 taken 15447106 times.
✓ Branch 1 taken 92659 times.
15539765 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4980
1/2
✓ Branch 0 taken 15447106 times.
✗ Branch 1 not taken.
15447106 draw_msgstr(3);
4981
4982
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4983 15676083 do_layer(framebuf, 0, screen_handles[4], offx, offy);
4984 15676083 });
4985
4986
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_layer_primitives(framebuf, 4);
4987
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 particles.draw(framebuf, true, 4);
4988
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, 4);
4989
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(4);
4990
4991
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4992 15676083 do_layer(framebuf, -1, screen_handles[0], offx, offy);
4993
2/2
✓ Branch 0 taken 14400195 times.
✓ Branch 1 taken 1275888 times.
15676083 if (get_qr(qr_OVERHEAD_COMBOS_L1_L2))
4994 {
4995 1275888 do_layer(framebuf, -1, screen_handles[1], offx, offy);
4996 1275888 do_layer(framebuf, -1, screen_handles[2], offx, offy);
4997 1275888 }
4998 15676083 });
4999
5000
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(framebuf, SPLAYER_OVERHEAD_CMB);
5001
5002 // Draw some flying sprites onto framebuf
5003
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 clear_clip_rect(framebuf);
5004
5/6
✓ Branch 0 taken 15494139 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15487811 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15539765 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
5005 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5006
5007 //Jumping Hero and jumping enemies are drawn on this layer.
5008
5/8
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15539765 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15539765 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14064 times.
✓ Branch 7 taken 15525701 times.
15539765 if(Hero.getZ() > (zfix)zinit.jump_hero_layer_threshold)
5009 {
5010
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw2(framebuf,false);
5011
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 Hero.draw(framebuf);
5012
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 chainlinks.draw(framebuf,true);
5013
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
5014
5015
3/4
✓ Branch 0 taken 16806 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✓ Branch 3 taken 14064 times.
16806 for(int32_t i=0; i<Lwpns.Count(); i++)
5016 {
5017
9/16
✓ Branch 0 taken 2742 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2742 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2742 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2742 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2742 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2742 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 239 times.
✓ Branch 15 taken 2503 times.
2742 if(Lwpns.spr(i)->z+Lwpns.spr(i)->fakez > (zfix)zinit.jump_hero_layer_threshold)
5018 {
5019
2/4
✓ Branch 0 taken 239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 239 times.
✗ Branch 3 not taken.
239 Lwpns.spr(i)->draw(framebuf);
5020 239 }
5021 2742 }
5022
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(framebuf, SPLAYER_LWEAP_ABOVE_DRAW);
5023
5024
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw(framebuf,false);
5025 14064 }
5026
5027
5/6
✓ Branch 0 taken 3288981 times.
✓ Branch 1 taken 12250784 times.
✓ Branch 2 taken 44334375 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32083591 times.
✓ Branch 5 taken 12250784 times.
47623356 if(!get_qr(qr_ENEMIESZAXIS)) for(int32_t i=0; i<guys.Count(); i++)
5028 {
5029
13/22
✓ Branch 0 taken 32083591 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32083591 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27177493 times.
✓ Branch 5 taken 4906098 times.
✓ Branch 6 taken 27177493 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 27177493 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 27177493 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 27177493 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 27177493 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 27177493 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 27177493 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 6568 times.
✓ Branch 21 taken 27170925 times.
32083591 if((isflier(guys.spr(i)->id)) || (guys.spr(i)->z+guys.spr(i)->fakez) > (zfix)zinit.jump_hero_layer_threshold)
5030 {
5031
2/4
✓ Branch 0 taken 4912666 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4912666 times.
✗ Branch 3 not taken.
4912666 guys.spr(i)->draw(framebuf);
5032 4912666 }
5033 44334375 }
5034 else
5035 {
5036
3/4
✓ Branch 0 taken 10545843 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7256862 times.
✓ Branch 3 taken 3288981 times.
10545843 for(int32_t i=0; i<guys.Count(); i++)
5037 {
5038
13/22
✓ Branch 0 taken 7256862 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7256862 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6081157 times.
✓ Branch 5 taken 1175705 times.
✓ Branch 6 taken 6081157 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6081157 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6081157 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 5594346 times.
✓ Branch 13 taken 486811 times.
✓ Branch 14 taken 5594346 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 5594346 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 5594346 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 5594346 times.
7256862 if((isflier(guys.spr(i)->id)) || guys.spr(i)->z > 0 || guys.spr(i)->fakez > 0)
5039 {
5040
2/4
✓ Branch 0 taken 1662516 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1662516 times.
✗ Branch 3 not taken.
1662516 guys.spr(i)->draw(framebuf);
5041 1662516 }
5042 7256862 }
5043 }
5044
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(framebuf, SPLAYER_NPC_AIRBORNE_DRAW);
5045
5046 // Draw the Moving Fairy above layer 3
5047
3/4
✓ Branch 0 taken 18684859 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3145094 times.
✓ Branch 3 taken 15539765 times.
18684859 for(int32_t i=0; i<items.Count(); i++)
5048
6/8
✓ Branch 0 taken 3145094 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 69867 times.
✓ Branch 3 taken 3075227 times.
✓ Branch 4 taken 69867 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 60153 times.
✓ Branch 7 taken 9714 times.
3205247 if(itemsbuf[items.spr(i)->id].family == itype_fairy && itemsbuf[items.spr(i)->id].misc3)
5049
2/4
✓ Branch 0 taken 60153 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60153 times.
✗ Branch 3 not taken.
60153 items.spr(i)->draw(framebuf);
5050
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(framebuf, SPLAYER_FAIRYITEM_DRAW);
5051
5052 // Draw some layers onto framebuf
5053
5054
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_draw_screen_clip(framebuf);
5055
5056
2/2
✓ Branch 0 taken 15525413 times.
✓ Branch 1 taken 14352 times.
15539765 if (lightbeam_present)
5057 {
5058 14352 color_map = &trans_table2;
5059
2/2
✓ Branch 0 taken 13114 times.
✓ Branch 1 taken 1238 times.
14352 if(get_qr(qr_LIGHTBEAM_TRANSPARENT))
5060
1/2
✓ Branch 0 taken 13114 times.
✗ Branch 1 not taken.
13114 draw_trans_sprite(framebuf, lightbeam_bmp, 0, playing_field_offset);
5061 else
5062
1/2
✓ Branch 0 taken 1238 times.
✗ Branch 1 not taken.
1238 masked_blit(lightbeam_bmp, framebuf, 0, 0, 0, playing_field_offset, 256, 176);
5063 14352 color_map = &trans_table;
5064 14352 }
5065
5066
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5067 15676083 do_layer(framebuf, 0, screen_handles[5], offx, offy);
5068 15676083 });
5069
5070
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_layer_primitives(framebuf, 5);
5071
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 particles.draw(framebuf, true, 5);
5072
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, 5);
5073
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(5);
5074
5075
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, -1); // 'overhead' freeform combos
5076
5077
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(framebuf, SPLAYER_OVERHEAD_FFC);
5078
5079
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5080 15676083 do_layer(framebuf, 0, screen_handles[6], offx, offy);
5081 15676083 });
5082
5083
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_layer_primitives(framebuf, 6);
5084
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 particles.draw(framebuf, true, 6);
5085
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, 6);
5086
5087 15539765 bool any_dark = false;
5088
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5089 15676083 mapscr* base_scr = screen_handles[0].scr;
5090 15676083 any_dark |= is_dark(base_scr);
5091 15676083 });
5092
5093 // Handle low drawn darkness
5094
4/4
✓ Branch 0 taken 1269552 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 1025781 times.
✓ Branch 3 taken 243771 times.
15539765 if(get_qr(qr_NEW_DARKROOM) && any_dark)
5095 {
5096
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
493776 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5097 250005 mapscr* base_scr = screen_handles[0].scr;
5098 250005 calc_darkroom_combos(base_scr, offx, offy + playing_field_offset);
5099 250005 calc_darkroom_ffcs(base_scr, 0, playing_field_offset);
5100 250005 });
5101
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
243771 if(showhero)
5102
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
243771 Hero.calc_darkroom_hero(0, -playing_field_offset);
5103
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 243771 times.
493776 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5104 250005 mapscr* base_scr = screen_handles[0].scr;
5105
2/2
✓ Branch 0 taken 245275 times.
✓ Branch 1 taken 4730 times.
250005 if (!is_dark(base_scr))
5106 {
5107 4730 offy += playing_field_offset;
5108 4730 rectfill(darkscr_bmp, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5109 4730 rectfill(darkscr_bmp_trans, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5110 4730 }
5111 250005 });
5112 243771 }
5113
5114 //Darkroom if under the subscreen
5115
6/6
✓ Branch 0 taken 1269552 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 823284 times.
✓ Branch 3 taken 446268 times.
✓ Branch 4 taken 231780 times.
✓ Branch 5 taken 591504 times.
15539765 if(get_qr(qr_NEW_DARKROOM) && get_qr(qr_NEWDARK_L6) && any_dark)
5116 {
5117
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 do_primitives(framebuf, SPLAYER_DARKROOM_UNDER);
5118
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 set_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5119
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231780 times.
231780 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5120 {
5121 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5122 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5123 }
5124
5125 231780 color_map = &trans_table2;
5126
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 231636 times.
231780 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5127 {
5128
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 draw_trans_sprite(framebuf, darkscr_bmp, 0, 0);
5129
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5130
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5131 144 }
5132 else
5133 {
5134
1/2
✓ Branch 0 taken 231636 times.
✗ Branch 1 not taken.
231636 masked_blit(darkscr_bmp, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
5135
1/2
✓ Branch 0 taken 231636 times.
✗ Branch 1 not taken.
231636 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5136 }
5137 231780 color_map = &trans_table;
5138
5139
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 set_clip_rect(framebuf, 0, 0, framebuf->w, framebuf->h);
5140
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 do_primitives(framebuf, SPLAYER_DARKROOM_OVER);
5141 231780 }
5142
5143
3/6
✓ Branch 0 taken 45626 times.
✓ Branch 1 taken 15494139 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45626 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
15539765 if (is_extended_height_mode() && lensclk && !FFCore.system_suspend[susptLENS])
5144 {
5145 draw_lens_over();
5146 --lensclk;
5147 }
5148
5149 // Draw some text on framebuf
5150
5151
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_clip_rect(framebuf,0,0,256,232);
5152
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 if(!get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5153
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(6);
5154
5155 // Draw the subscreen, without clipping
5156
2/2
✓ Branch 0 taken 6288381 times.
✓ Branch 1 taken 9251384 times.
15539765 if(get_qr(qr_SUBSCREENOVERSPRITES))
5157 {
5158
2/4
✓ Branch 0 taken 6288381 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6288381 times.
✗ Branch 3 not taken.
6288381 put_passive_subscr(framebuf, 0, 0, game->should_show_time(), sspUP);
5159
5160 // Draw primitives over subscren
5161
1/2
✓ Branch 0 taken 6288381 times.
✗ Branch 1 not taken.
6288381 do_primitives(framebuf, 7); //Layer '7' appears above subscreen if quest rule is set
5162 6288381 }
5163
5164
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539765 times.
15539765 if(get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5165 draw_msgstr(6);
5166
5167 // Handle high-drawn darkness
5168
6/6
✓ Branch 0 taken 1269552 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 446268 times.
✓ Branch 3 taken 823284 times.
✓ Branch 4 taken 11991 times.
✓ Branch 5 taken 434277 times.
15539765 if(get_qr(qr_NEW_DARKROOM) && !get_qr(qr_NEWDARK_L6) && any_dark)
5169 {
5170
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 do_primitives(framebuf, SPLAYER_DARKROOM_UNDER);
5171
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 set_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5172
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5173 {
5174 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5175 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5176 }
5177
5178 11991 color_map = &trans_table2;
5179
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5180 {
5181 draw_trans_sprite(framebuf, darkscr_bmp, 0, 0);
5182 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5183 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5184 }
5185 else
5186 {
5187
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 masked_blit(darkscr_bmp, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
5188
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5189 }
5190 11991 color_map = &trans_table;
5191
5192
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 set_clip_rect(framebuf, 0, 0, framebuf->w, framebuf->h);
5193
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 do_primitives(framebuf, SPLAYER_DARKROOM_OVER);
5194 11991 }
5195
5196
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, 7);
5197
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(7);
5198
5199
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_clip_rect(scrollbuf, 0, 0, scrollbuf->w, scrollbuf->h);
5200
3/4
✓ Branch 0 taken 14938100 times.
✓ Branch 1 taken 601665 times.
✓ Branch 2 taken 14938100 times.
✗ Branch 3 not taken.
15539765 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_POST_DRAW);
5201 76698313 }
5202
5203 // TODO: separate setting door data and drawing door
5204 28153 void put_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t type, bool redraw, bool even_walls)
5205 {
5206
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28153 times.
28153 if (type > 8) return;
5207
5208 28153 int32_t d=scr->door_combo_set;
5209
5210
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15611 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12542 times.
28153 switch(type)
5211 {
5212 case dt_wall:
5213 case dt_walk:
5214 if(!even_walls)
5215 break;
5216 [[fallthrough]];
5217 case dt_pass:
5218
3/4
✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 11506 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1036 times.
12542 if(!get_qr(qr_REPLACEOPENDOORS) && !even_walls)
5219 1036 break;
5220 [[fallthrough]];
5221 case dt_lock:
5222 case dt_shut:
5223 case dt_boss:
5224 case dt_olck:
5225 case dt_osht:
5226 case dt_obos:
5227 case dt_bomb:
5228
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 7259 times.
✓ Branch 2 taken 6784 times.
✓ Branch 3 taken 6362 times.
✓ Branch 4 taken 6712 times.
27117 switch(side)
5229 {
5230 case up:
5231 7259 scr->data[pos] = DoorComboSets[d].doorcombo_u[type][0];
5232 7259 scr->cset[pos] = DoorComboSets[d].doorcset_u[type][0];
5233 7259 scr->sflag[pos] = 0;
5234 7259 scr->data[pos+1] = DoorComboSets[d].doorcombo_u[type][1];
5235 7259 scr->cset[pos+1] = DoorComboSets[d].doorcset_u[type][1];
5236 7259 scr->sflag[pos+1] = 0;
5237 7259 scr->data[pos+16] = DoorComboSets[d].doorcombo_u[type][2];
5238 7259 scr->cset[pos+16] = DoorComboSets[d].doorcset_u[type][2];
5239 7259 scr->sflag[pos+16] = 0;
5240 7259 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_u[type][3];
5241 7259 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_u[type][3];
5242 7259 scr->sflag[pos+16+1] = 0;
5243
5244
2/2
✓ Branch 0 taken 5435 times.
✓ Branch 1 taken 1824 times.
7259 if(redraw)
5245 {
5246 3648 putcombo(dest,(pos&15)<<4,pos&0xF0,
5247 1824 DoorComboSets[d].doorcombo_u[type][0],
5248 1824 DoorComboSets[d].doorcset_u[type][0]);
5249 3648 putcombo(dest,((pos&15)<<4)+16,pos&0xF0,
5250 1824 DoorComboSets[d].doorcombo_u[type][1],
5251 1824 DoorComboSets[d].doorcset_u[type][1]);
5252 1824 }
5253
5254 7259 break;
5255
5256 case down:
5257 6784 scr->data[pos] = DoorComboSets[d].doorcombo_d[type][0];
5258 6784 scr->cset[pos] = DoorComboSets[d].doorcset_d[type][0];
5259 6784 scr->sflag[pos] = 0;
5260 6784 scr->data[pos+1] = DoorComboSets[d].doorcombo_d[type][1];
5261 6784 scr->cset[pos+1] = DoorComboSets[d].doorcset_d[type][1];
5262 6784 scr->sflag[pos+1] = 0;
5263 6784 scr->data[pos+16] = DoorComboSets[d].doorcombo_d[type][2];
5264 6784 scr->cset[pos+16] = DoorComboSets[d].doorcset_d[type][2];
5265 6784 scr->sflag[pos+16] = 0;
5266 6784 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_d[type][3];
5267 6784 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_d[type][3];
5268 6784 scr->sflag[pos+16+1] = 0;
5269
5270
2/2
✓ Branch 0 taken 5463 times.
✓ Branch 1 taken 1321 times.
6784 if(redraw)
5271 {
5272 2642 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5273 1321 DoorComboSets[d].doorcombo_d[type][2],
5274 1321 DoorComboSets[d].doorcset_d[type][2]);
5275 2642 putcombo(dest,((pos&15)<<4)+16,(pos&0xF0)+16,
5276 1321 DoorComboSets[d].doorcombo_d[type][3],
5277 1321 DoorComboSets[d].doorcset_d[type][3]);
5278 1321 }
5279
5280 6784 break;
5281
5282 case left:
5283 6362 scr->data[pos] = DoorComboSets[d].doorcombo_l[type][0];
5284 6362 scr->cset[pos] = DoorComboSets[d].doorcset_l[type][0];
5285 6362 scr->sflag[pos] = 0;
5286 6362 scr->data[pos+1] = DoorComboSets[d].doorcombo_l[type][1];
5287 6362 scr->cset[pos+1] = DoorComboSets[d].doorcset_l[type][1];
5288 6362 scr->sflag[pos+1] = 0;
5289 6362 scr->data[pos+16] = DoorComboSets[d].doorcombo_l[type][2];
5290 6362 scr->cset[pos+16] = DoorComboSets[d].doorcset_l[type][2];
5291 6362 scr->sflag[pos+16] = 0;
5292 6362 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_l[type][3];
5293 6362 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_l[type][3];
5294 6362 scr->sflag[pos+16+1] = 0;
5295 6362 scr->data[pos+32] = DoorComboSets[d].doorcombo_l[type][4];
5296 6362 scr->cset[pos+32] = DoorComboSets[d].doorcset_l[type][4];
5297 6362 scr->sflag[pos+32] = 0;
5298 6362 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_l[type][5];
5299 6362 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_l[type][5];
5300 6362 scr->sflag[pos+32+1] = 0;
5301
5302
2/2
✓ Branch 0 taken 4873 times.
✓ Branch 1 taken 1489 times.
6362 if(redraw)
5303 {
5304 2978 putcombo(dest,(pos&15)<<4,pos&0xF0,
5305 1489 DoorComboSets[d].doorcombo_l[type][0],
5306 1489 DoorComboSets[d].doorcset_l[type][0]);
5307 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5308 1489 DoorComboSets[d].doorcombo_l[type][2],
5309 1489 DoorComboSets[d].doorcset_l[type][2]);
5310 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5311 1489 DoorComboSets[d].doorcombo_l[type][4],
5312 1489 DoorComboSets[d].doorcset_l[type][4]);
5313 1489 }
5314
5315 6362 break;
5316
5317 case right:
5318 6712 scr->data[pos] = DoorComboSets[d].doorcombo_r[type][0];
5319 6712 scr->cset[pos] = DoorComboSets[d].doorcset_r[type][0];
5320 6712 scr->sflag[pos] = 0;
5321 6712 scr->data[pos+1] = DoorComboSets[d].doorcombo_r[type][1];
5322 6712 scr->cset[pos+1] = DoorComboSets[d].doorcset_r[type][1];
5323 6712 scr->sflag[pos+1] = 0;
5324 6712 scr->data[pos+16] = DoorComboSets[d].doorcombo_r[type][2];
5325 6712 scr->cset[pos+16] = DoorComboSets[d].doorcset_r[type][2];
5326 6712 scr->sflag[pos+16] = 0;
5327 6712 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_r[type][3];
5328 6712 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_r[type][3];
5329 6712 scr->sflag[pos+16+1] = 0;
5330 6712 scr->data[pos+32] = DoorComboSets[d].doorcombo_r[type][4];
5331 6712 scr->cset[pos+32] = DoorComboSets[d].doorcset_r[type][4];
5332 6712 scr->sflag[pos+32] = 0;
5333 6712 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_r[type][5];
5334 6712 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_r[type][5];
5335 6712 scr->sflag[pos+32+1] = 0;
5336
5337
2/2
✓ Branch 0 taken 5058 times.
✓ Branch 1 taken 1654 times.
6712 if(redraw)
5338 {
5339 3308 putcombo(dest,(pos&15)<<4,pos&0xF0,
5340 1654 DoorComboSets[d].doorcombo_r[type][0],
5341 1654 DoorComboSets[d].doorcset_r[type][0]);
5342 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5343 1654 DoorComboSets[d].doorcombo_r[type][2],
5344 1654 DoorComboSets[d].doorcset_r[type][2]);
5345 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5346 1654 DoorComboSets[d].doorcombo_r[type][4],
5347 1654 DoorComboSets[d].doorcset_r[type][4]);
5348 1654 }
5349
5350 6712 break;
5351 }
5352
5353 27117 break;
5354
5355 default:
5356 break;
5357 }
5358 28153 }
5359
5360 706556 static void over_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t offx, int32_t offy)
5361 {
5362 706556 int32_t door_combo_set = scr->door_combo_set;
5363 706556 int32_t x = (pos&15)<<4;
5364 706556 int32_t y = (pos&0xF0);
5365 706556 int32_t d = door_combo_set;
5366 706556 x += offx;
5367 706556 y += offy;
5368
5369
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 161136 times.
✓ Branch 2 taken 179643 times.
✓ Branch 3 taken 196353 times.
✓ Branch 4 taken 169424 times.
706556 switch(side)
5370 {
5371 case up:
5372 322272 overcombo2(dest,x,y,
5373 161136 DoorComboSets[d].bombdoorcombo_u[0],
5374 161136 DoorComboSets[d].bombdoorcset_u[0]);
5375 322272 overcombo2(dest,x+16,y,
5376 161136 DoorComboSets[d].bombdoorcombo_u[1],
5377 161136 DoorComboSets[d].bombdoorcset_u[1]);
5378 161136 break;
5379
5380 case down:
5381 359286 overcombo2(dest,x,y,
5382 179643 DoorComboSets[d].bombdoorcombo_d[0],
5383 179643 DoorComboSets[d].bombdoorcset_d[0]);
5384 359286 overcombo2(dest,x+16,y,
5385 179643 DoorComboSets[d].bombdoorcombo_d[1],
5386 179643 DoorComboSets[d].bombdoorcset_d[1]);
5387 179643 break;
5388
5389 case left:
5390 392706 overcombo2(dest,x,y,
5391 196353 DoorComboSets[d].bombdoorcombo_l[0],
5392 196353 DoorComboSets[d].bombdoorcset_l[0]);
5393 392706 overcombo2(dest,x,y+16,
5394 196353 DoorComboSets[d].bombdoorcombo_l[1],
5395 196353 DoorComboSets[d].bombdoorcset_l[1]);
5396 392706 overcombo2(dest,x,y+16,
5397 196353 DoorComboSets[d].bombdoorcombo_l[2],
5398 196353 DoorComboSets[d].bombdoorcset_l[2]);
5399 196353 break;
5400
5401 case right:
5402 338848 overcombo2(dest,x,y,
5403 169424 DoorComboSets[d].bombdoorcombo_r[0],
5404 169424 DoorComboSets[d].bombdoorcset_r[0]);
5405 338848 overcombo2(dest,x,y+16,
5406 169424 DoorComboSets[d].bombdoorcombo_r[1],
5407 169424 DoorComboSets[d].bombdoorcset_r[1]);
5408 338848 overcombo2(dest,x,y+16,
5409 169424 DoorComboSets[d].bombdoorcombo_r[2],
5410 169424 DoorComboSets[d].bombdoorcset_r[2]);
5411 169424 break;
5412 }
5413 706556 }
5414
5415 47568 void update_door(mapscr* scr, int32_t side, int32_t door, bool even_walls)
5416 {
5417
7/8
✓ Branch 0 taken 47460 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 47460 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22925 times.
✓ Branch 5 taken 24535 times.
✓ Branch 6 taken 530 times.
✓ Branch 7 taken 22395 times.
47568 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5418 25173 return;
5419
5420 int32_t doortype;
5421
5422
10/12
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 655 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12492 times.
✓ Branch 5 taken 910 times.
✓ Branch 6 taken 1553 times.
✓ Branch 7 taken 3192 times.
✓ Branch 8 taken 1694 times.
✓ Branch 9 taken 172 times.
✓ Branch 10 taken 67 times.
✓ Branch 11 taken 1138 times.
22395 switch(door)
5423 {
5424 case dWALL:
5425 doortype=dt_wall;
5426 break;
5427
5428 case dWALK:
5429 doortype=dt_walk;
5430 break;
5431
5432 case dOPEN:
5433 12492 doortype=dt_pass;
5434 12492 break;
5435
5436 case dLOCKED:
5437 910 doortype=dt_lock;
5438 910 break;
5439
5440 case dUNLOCKED:
5441 1553 doortype=dt_olck;
5442 1553 break;
5443
5444 case dSHUTTER:
5445
3/4
✓ Branch 0 taken 2783 times.
✓ Branch 1 taken 409 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2783 times.
3192 if(screenscrolling && ((HeroDir()^1)==side))
5446 {
5447 doortype=dt_osht;
5448 get_screen_state(scr->screen).open_doors = -4;
5449 break;
5450 }
5451
5452 [[fallthrough]];
5453 case d1WAYSHUTTER:
5454 3714 doortype=dt_shut;
5455 3714 break;
5456
5457 case dOPENSHUTTER:
5458 1694 doortype=dt_osht;
5459 1694 break;
5460
5461 case dBOSS:
5462 172 doortype=dt_boss;
5463 172 break;
5464
5465 case dOPENBOSS:
5466 67 doortype=dt_obos;
5467 67 break;
5468
5469 case dBOMBED:
5470 1138 doortype=dt_bomb;
5471 1138 break;
5472
5473 default:
5474 655 return;
5475 }
5476
5477
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5629 times.
✓ Branch 2 taken 5770 times.
✓ Branch 3 taken 5111 times.
✓ Branch 4 taken 5230 times.
21740 switch(side)
5478 {
5479 case up:
5480 5629 put_door(scr,nullptr,7,side,doortype,false,even_walls);
5481 5629 break;
5482
5483 case down:
5484 5770 put_door(scr,nullptr,151,side,doortype,false,even_walls);
5485 5770 break;
5486
5487 case left:
5488 5111 put_door(scr,nullptr,64,side,doortype,false,even_walls);
5489 5111 break;
5490
5491 case right:
5492 5230 put_door(scr,nullptr,78,side,doortype,false,even_walls);
5493 5230 break;
5494 }
5495 47568 }
5496
5497 6504 void putdoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t door, bool redraw, bool even_walls)
5498 {
5499 /*
5500 #define dWALL 0 // 000 0
5501 #define dBOMB 6 // 011 0
5502 #define 8 // 100 0
5503 enum {dt_pass=0, dt_lock, dt_shut, dt_boss, dt_olck, dt_osht, dt_obos, dt_wall, dt_bomb, dt_walk, dt_max};
5504 */
5505
5506
7/8
✓ Branch 0 taken 6504 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6500 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 6417 times.
✓ Branch 5 taken 83 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 6409 times.
6504 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5507 91 return;
5508
5509 int32_t doortype;
5510
5511
8/12
✓ Branch 0 taken 227 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 362 times.
✓ Branch 7 taken 1530 times.
✓ Branch 8 taken 3958 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 51 times.
✓ Branch 11 taken 231 times.
6413 switch(door)
5512 {
5513 case dWALL:
5514 doortype=dt_wall;
5515 break;
5516
5517 case dWALK:
5518 doortype=dt_walk;
5519 break;
5520
5521 case dOPEN:
5522 50 doortype=dt_pass;
5523 50 break;
5524
5525 case dLOCKED:
5526 doortype=dt_lock;
5527 break;
5528
5529 case dUNLOCKED:
5530 362 doortype=dt_olck;
5531 362 break;
5532
5533 case dSHUTTER:
5534
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1530 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1530 if(screenscrolling && ((HeroDir()^1)==side))
5535 {
5536 doortype=dt_osht;
5537 get_screen_state(cur_screen).open_doors = -4;
5538 break;
5539 }
5540
5541 [[fallthrough]];
5542 case d1WAYSHUTTER:
5543 1757 doortype=dt_shut;
5544 1757 break;
5545
5546 case dOPENSHUTTER:
5547 3958 doortype=dt_osht;
5548 3958 break;
5549
5550 case dBOSS:
5551 4 doortype=dt_boss;
5552 4 break;
5553
5554 case dOPENBOSS:
5555 51 doortype=dt_obos;
5556 51 break;
5557
5558 case dBOMBED:
5559 231 doortype=dt_bomb;
5560 231 break;
5561
5562 default:
5563 return;
5564 }
5565
5566
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1860 times.
✓ Branch 2 taken 1357 times.
✓ Branch 3 taken 1514 times.
✓ Branch 4 taken 1682 times.
6413 switch(side)
5567 {
5568 case up:
5569
2/2
✓ Branch 0 taken 1791 times.
✓ Branch 1 taken 69 times.
1860 switch(door)
5570 {
5571 case dBOMBED:
5572
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
138 if(redraw)
5573 {
5574 69 over_door(scr,dest,39,side,0,0);
5575 69 }
5576 [[fallthrough]];
5577 default:
5578 1860 put_door(scr,dest,7,side,doortype,redraw, even_walls);
5579 1860 break;
5580 }
5581
5582 1860 break;
5583
5584 case down:
5585
2/2
✓ Branch 0 taken 1318 times.
✓ Branch 1 taken 39 times.
1357 switch(door)
5586 {
5587 case dBOMBED:
5588
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
78 if(redraw)
5589 {
5590 39 over_door(scr,dest,135,side,0,0);
5591 39 }
5592 [[fallthrough]];
5593 default:
5594 1357 put_door(scr,dest,151,side,doortype,redraw, even_walls);
5595 1357 break;
5596 }
5597
5598 1357 break;
5599
5600 case left:
5601
2/2
✓ Branch 0 taken 1463 times.
✓ Branch 1 taken 51 times.
1514 switch(door)
5602 {
5603 case dBOMBED:
5604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
102 if(redraw)
5605 {
5606 51 over_door(scr,dest,66,side,0,0);
5607 51 }
5608 [[fallthrough]];
5609 default:
5610 1514 put_door(scr,dest,64,side,doortype,redraw, even_walls);
5611 1514 break;
5612 }
5613
5614 1514 break;
5615
5616 case right:
5617
2/2
✓ Branch 0 taken 1610 times.
✓ Branch 1 taken 72 times.
1682 switch(door)
5618 {
5619 case dBOMBED:
5620
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
144 if(redraw)
5621 {
5622 72 over_door(scr,dest,77,side,0,0);
5623 72 }
5624 [[fallthrough]];
5625 default:
5626 1682 put_door(scr,dest,78,side,doortype,redraw, even_walls);
5627 1682 break;
5628 }
5629
5630 1682 break;
5631 }
5632 6504 }
5633
5634 586 void putcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5635 {
5636
1/2
✓ Branch 0 taken 586 times.
✗ Branch 1 not taken.
586 if(combo!=0)
5637 {
5638 586 putcombo(dest,x, y, combo, cset);
5639 586 }
5640 586 }
5641
5642 293 void overcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5643 {
5644
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 74 times.
293 if(combo!=0)
5645 {
5646 219 overcombo(dest,x, y, combo, cset);
5647 219 }
5648 293 }
5649
5650 125 void showbombeddoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t offx, int32_t offy)
5651 {
5652 125 int32_t d = scr->door_combo_set;
5653
5654
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 37 times.
125 switch(side)
5655 {
5656 case up:
5657 86 putcombo_not_zero(dest,((7&15)<<4) + offx,(7&0xF0) + offy,
5658 43 DoorComboSets[d].doorcombo_u[dt_bomb][0],
5659 43 DoorComboSets[d].doorcset_u[dt_bomb][0]);
5660 86 putcombo_not_zero(dest,((8&15)<<4) + offx,(8&0xF0) + offy,
5661 43 DoorComboSets[d].doorcombo_u[dt_bomb][1],
5662 43 DoorComboSets[d].doorcset_u[dt_bomb][1]);
5663 86 putcombo_not_zero(dest,((23&15)<<4) + offx,(23&0xF0) + offy,
5664 43 DoorComboSets[d].doorcombo_u[dt_bomb][2],
5665 43 DoorComboSets[d].doorcset_u[dt_bomb][2]);
5666 86 putcombo_not_zero(dest,((24&15)<<4) + offx,(24&0xF0) + offy,
5667 43 DoorComboSets[d].doorcombo_u[dt_bomb][3],
5668 43 DoorComboSets[d].doorcset_u[dt_bomb][3]);
5669 86 overcombo_not_zero(dest,((39&15)<<4) + offx,(39&0xF0) + offy,
5670 43 DoorComboSets[d].bombdoorcombo_u[0],
5671 43 DoorComboSets[d].bombdoorcset_u[0]);
5672 86 overcombo_not_zero(dest,((40&15)<<4) + offx,(40&0xF0) + offy,
5673 43 DoorComboSets[d].bombdoorcombo_u[1],
5674 43 DoorComboSets[d].bombdoorcset_u[1]);
5675 43 break;
5676
5677 case down:
5678 78 putcombo_not_zero(dest,((151&15)<<4) + offx,(151&0xF0) + offy,
5679 39 DoorComboSets[d].doorcombo_d[dt_bomb][0],
5680 39 DoorComboSets[d].doorcset_d[dt_bomb][0]);
5681 78 putcombo_not_zero(dest,((152&15)<<4) + offx,(152&0xF0) + offy,
5682 39 DoorComboSets[d].doorcombo_d[dt_bomb][1],
5683 39 DoorComboSets[d].doorcset_d[dt_bomb][1]);
5684 78 putcombo_not_zero(dest,((167&15)<<4) + offx,(167&0xF0) + offy,
5685 39 DoorComboSets[d].doorcombo_d[dt_bomb][2],
5686 39 DoorComboSets[d].doorcset_d[dt_bomb][2]);
5687 78 putcombo_not_zero(dest,((168&15)<<4) + offx,(168&0xF0) + offy,
5688 39 DoorComboSets[d].doorcombo_d[dt_bomb][3],
5689 39 DoorComboSets[d].doorcset_d[dt_bomb][3]);
5690 78 overcombo_not_zero(dest,((135&15)<<4) + offx,(135&0xF0) + offy,
5691 39 DoorComboSets[d].bombdoorcombo_d[0],
5692 39 DoorComboSets[d].bombdoorcset_d[0]);
5693 78 overcombo_not_zero(dest,((136&15)<<4) + offx,(136&0xF0) + offy,
5694 39 DoorComboSets[d].bombdoorcombo_d[1],
5695 39 DoorComboSets[d].bombdoorcset_d[1]);
5696 39 break;
5697
5698 case left:
5699 12 putcombo_not_zero(dest,((64&15)<<4) + offx,(64&0xF0) + offy,
5700 6 DoorComboSets[d].doorcombo_l[dt_bomb][0],
5701 6 DoorComboSets[d].doorcset_l[dt_bomb][0]);
5702 12 putcombo_not_zero(dest,((65&15)<<4) + offx,(65&0xF0) + offy,
5703 6 DoorComboSets[d].doorcombo_l[dt_bomb][1],
5704 6 DoorComboSets[d].doorcset_l[dt_bomb][1]);
5705 12 putcombo_not_zero(dest,((80&15)<<4) + offx,(80&0xF0) + offy,
5706 6 DoorComboSets[d].doorcombo_l[dt_bomb][2],
5707 6 DoorComboSets[d].doorcset_l[dt_bomb][2]);
5708 12 putcombo_not_zero(dest,((81&15)<<4) + offx,(81&0xF0) + offy,
5709 6 DoorComboSets[d].doorcombo_l[dt_bomb][3],
5710 6 DoorComboSets[d].doorcset_l[dt_bomb][3]);
5711 12 putcombo_not_zero(dest,((96&15)<<4) + offx,(96&0xF0) + offy,
5712 6 DoorComboSets[d].doorcombo_l[dt_bomb][4],
5713 6 DoorComboSets[d].doorcset_l[dt_bomb][4]);
5714 12 putcombo_not_zero(dest,((97&15)<<4) + offx,(97&0xF0) + offy,
5715 6 DoorComboSets[d].doorcombo_l[dt_bomb][5],
5716 6 DoorComboSets[d].doorcset_l[dt_bomb][5]);
5717 12 overcombo_not_zero(dest,((66&15)<<4) + offx,(66&0xF0) + offy,
5718 6 DoorComboSets[d].bombdoorcombo_l[0],
5719 6 DoorComboSets[d].bombdoorcset_l[0]);
5720 12 overcombo_not_zero(dest,((82&15)<<4) + offx,(82&0xF0) + offy,
5721 6 DoorComboSets[d].bombdoorcombo_l[1],
5722 6 DoorComboSets[d].bombdoorcset_l[1]);
5723 12 overcombo_not_zero(dest,((98&15)<<4) + offx,(98&0xF0) + offy,
5724 6 DoorComboSets[d].bombdoorcombo_l[2],
5725 6 DoorComboSets[d].bombdoorcset_l[2]);
5726 6 break;
5727
5728 case right:
5729 74 putcombo_not_zero(dest,((78&15)<<4) + offx,(78&0xF0) + offy,
5730 37 DoorComboSets[d].doorcombo_r[dt_bomb][0],
5731 37 DoorComboSets[d].doorcset_r[dt_bomb][0]);
5732 74 putcombo_not_zero(dest,((79&15)<<4) + offx,(79&0xF0) + offy,
5733 37 DoorComboSets[d].doorcombo_r[dt_bomb][1],
5734 37 DoorComboSets[d].doorcset_r[dt_bomb][1]);
5735 74 putcombo_not_zero(dest,((94&15)<<4) + offx,(94&0xF0) + offy,
5736 37 DoorComboSets[d].doorcombo_r[dt_bomb][2],
5737 37 DoorComboSets[d].doorcset_r[dt_bomb][2]);
5738 74 putcombo_not_zero(dest,((95&15)<<4) + offx,(95&0xF0) + offy,
5739 37 DoorComboSets[d].doorcombo_r[dt_bomb][3],
5740 37 DoorComboSets[d].doorcset_r[dt_bomb][3]);
5741 74 putcombo_not_zero(dest,((110&15)<<4) + offx,(110&0xF0) + offy,
5742 37 DoorComboSets[d].doorcombo_r[dt_bomb][4],
5743 37 DoorComboSets[d].doorcset_r[dt_bomb][4]);
5744 74 putcombo_not_zero(dest,((111&15)<<4) + offx,(111&0xF0) + offy,
5745 37 DoorComboSets[d].doorcombo_r[dt_bomb][5],
5746 37 DoorComboSets[d].doorcset_r[dt_bomb][5]);
5747 74 overcombo_not_zero(dest,((77&15)<<4) + offx,(77&0xF0) + offy,
5748 37 DoorComboSets[d].bombdoorcombo_r[0],
5749 37 DoorComboSets[d].bombdoorcset_r[0]);
5750 74 overcombo_not_zero(dest,((93&15)<<4) + offx,(93&0xF0) + offy,
5751 37 DoorComboSets[d].bombdoorcombo_r[1],
5752 37 DoorComboSets[d].bombdoorcset_r[1]);
5753 74 overcombo_not_zero(dest,((109&15)<<4) + offx,(109&0xF0) + offy,
5754 37 DoorComboSets[d].bombdoorcombo_r[2],
5755 37 DoorComboSets[d].bombdoorcset_r[2]);
5756 37 break;
5757 }
5758 125 }
5759
5760 5357371 void openshutters(mapscr* scr)
5761 {
5762 5357371 bool opened_door = false;
5763
2/2
✓ Branch 0 taken 5357371 times.
✓ Branch 1 taken 21429484 times.
26786855 for(int32_t i=0; i<4; i++)
5764
2/2
✓ Branch 0 taken 21425526 times.
✓ Branch 1 taken 3958 times.
21433442 if(scr->door[i]==dSHUTTER)
5765 {
5766 3958 putdoor(scr, scrollbuf, i, dOPENSHUTTER);
5767 3958 scr->door[i]=dOPENSHUTTER;
5768 3958 opened_door = true;
5769 3958 }
5770
5771 5357371 auto& combo_cache = combo_caches::shutter;
5772 2020175719 for_every_combo_in_screen(create_screen_handles(scr), [&](const auto& handle) {
5773
3/4
✓ Branch 0 taken 2013207673 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 1610668 times.
✗ Branch 3 not taken.
2014818348 if (!combo_cache.minis[handle.data()].shutter)
5774 2014818341 return;
5775
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
5776 7 return trig.trigger_flags.get(TRIGFLAG_SHUTTER);
5777 });
5778 2014818348 });
5779
5780
2/2
✓ Branch 0 taken 5354640 times.
✓ Branch 1 taken 2731 times.
5357371 if(opened_door)
5781 2731 sfx(WAV_DOOR,128);
5782 5357371 }
5783
5784 15116782 void clear_darkroom_bitmaps()
5785 {
5786 15116782 clear_to_color(darkscr_bmp, game->get_darkscr_color());
5787 15116782 clear_to_color(darkscr_bmp_trans, game->get_darkscr_color());
5788 15116782 }
5789
5790 16031111 bool is_dark(const mapscr* scr)
5791 {
5792 16031111 bool dark = scr->flags&fDARK;
5793
2/2
✓ Branch 0 taken 3722 times.
✓ Branch 1 taken 16027389 times.
16031111 if (region_is_lit) return !dark;
5794 16027389 return dark;
5795 16031111 }
5796
5797 39226 bool scrolling_is_dark(const mapscr* scr)
5798 {
5799 39226 bool dark = scr->flags&fDARK;
5800
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 39224 times.
39226 if (scrolling_region_is_lit) return !dark;
5801 39224 return dark;
5802 39226 }
5803
5804 36758 bool is_any_dark()
5805 {
5806 36758 bool dark = false;
5807 74772 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
5808 38014 dark |= (bool)(is_dark(scr));
5809 38014 });
5810 36758 return dark;
5811 }
5812
5813 412 static mapscr prev_origin_scrs[7];
5814 412 static std::set<int> loadscr_ffc_script_ids_to_remove;
5815
5816 static void handle_screen_overlay(const std::vector<mapscr*>& screens)
5817 {
5818 mapscr* base_scr = screens[0];
5819 mapscr* previous_scr = &prev_origin_scrs[0];
5820
5821 for (int i = 0; i < 176; i++)
5822 {
5823 if (base_scr->data[i] == 0)
5824 {
5825 base_scr->data[i] = previous_scr->data[i];
5826 base_scr->sflag[i] = previous_scr->sflag[i];
5827 base_scr->cset[i] = previous_scr->cset[i];
5828 }
5829 }
5830
5831 for (int i = 0; i < 6; i++)
5832 {
5833 if (previous_scr->layermap[i] > 0 && base_scr->layermap[i] > 0)
5834 {
5835 int lm = (base_scr->layermap[i]-1)*MAPSCRS+base_scr->layerscreen[i];
5836 int fm = (previous_scr->layermap[i]-1)*MAPSCRS+previous_scr->layerscreen[i];
5837
5838 for (int j = 0; j < 176; j++)
5839 {
5840 if (TheMaps[lm].data[j] == 0)
5841 {
5842 TheMaps[lm].data[j] = TheMaps[fm].data[j];
5843 TheMaps[lm].sflag[j] = TheMaps[fm].sflag[j];
5844 TheMaps[lm].cset[j] = TheMaps[fm].cset[j];
5845 }
5846 }
5847 }
5848 }
5849
5850 for (int i = 1; i <= 6; i++)
5851 {
5852 mapscr* scr = screens[i];
5853 previous_scr = &prev_origin_scrs[i];
5854
5855 if (scr->layermap[i] > 0)
5856 {
5857 for (int y = 0; y < 11; y++)
5858 {
5859 for (int x = 0; x < 16; x++)
5860 {
5861 int c = y*16+x;
5862
5863 if (scr->data[c]==0)
5864 {
5865 scr->data[c] = previous_scr->data[c];
5866 scr->sflag[c] = previous_scr->sflag[c];
5867 scr->cset[c] = previous_scr->cset[c];
5868 }
5869 }
5870 }
5871 }
5872 }
5873 }
5874
5875 37098 static void load_a_screen_and_layers_init(int dmap, int screen, int ldir, bool screen_overlay, bool ffc_overlay)
5876 {
5877 37098 std::vector<mapscr*> screens;
5878
5879
1/2
✓ Branch 0 taken 37098 times.
✗ Branch 1 not taken.
37098 const mapscr* source = get_canonical_scr(cur_map, screen);
5880
2/4
✓ Branch 0 taken 37098 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 37098 times.
✗ Branch 3 not taken.
37098 mapscr* base_scr = new mapscr(*source);
5881 37098 temporary_screens[screen*7] = base_scr;
5882
1/2
✓ Branch 0 taken 37098 times.
✗ Branch 1 not taken.
37098 screens.push_back(base_scr);
5883
5884 37098 base_scr->valid |= mVALID; // layer 0 is always valid
5885
5886
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 35854 times.
37098 if (screen == cur_screen)
5887 35854 origin_scr = base_scr;
5888
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 35854 times.
37098 if (screen == hero_screen)
5889 35854 hero_scr = prev_hero_scr = base_scr;
5890
5891
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 36979 times.
37098 if (source->script > 0)
5892
1/2
✓ Branch 0 taken 119 times.
✗ Branch 1 not taken.
119 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
5893
5894
2/2
✓ Branch 0 taken 37098 times.
✓ Branch 1 taken 222588 times.
259686 for (int i = 0; i < 6; i++)
5895 {
5896
2/2
✓ Branch 0 taken 173511 times.
✓ Branch 1 taken 49077 times.
222588 if(source->layermap[i]>0)
5897 {
5898
3/6
✓ Branch 0 taken 49077 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49077 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 49077 times.
✗ Branch 5 not taken.
49077 mapscr* layer_scr = new mapscr(*get_canonical_scr(source->layermap[i]-1, source->layerscreen[i]));
5899 49077 layer_scr->map = cur_map;
5900 49077 layer_scr->screen = screen;
5901
1/2
✓ Branch 0 taken 49077 times.
✗ Branch 1 not taken.
49077 screens.push_back(layer_scr);
5902 49077 }
5903 else
5904 {
5905
1/2
✓ Branch 0 taken 173511 times.
✗ Branch 1 not taken.
173511 mapscr* layer_scr = new mapscr();
5906 173511 layer_scr->map = cur_map;
5907 173511 layer_scr->screen = screen;
5908
1/2
✓ Branch 0 taken 173511 times.
✗ Branch 1 not taken.
173511 screens.push_back(layer_scr);
5909 }
5910 222588 temporary_screens[screen*7+i+1] = screens[i+1];
5911 222588 }
5912
5913
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37098 times.
37098 if (screen_overlay)
5914 handle_screen_overlay(screens);
5915
5916
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 36954 times.
37098 if (ffc_overlay)
5917 {
5918 144 mapscr* previous_scr = &prev_origin_scrs[0];
5919
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 int num_ffcs = previous_scr->numFFC();
5920
2/2
✓ Branch 0 taken 4608 times.
✓ Branch 1 taken 144 times.
4752 for (int i = 0; i < num_ffcs; i++)
5921 {
5922
2/2
✓ Branch 0 taken 4334 times.
✓ Branch 1 taken 274 times.
4608 if ((previous_scr->ffcs[i].flags&ffc_carryover))
5923 {
5924
2/4
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 274 times.
✗ Branch 3 not taken.
274 auto& ffc = base_scr->getFFC(i) = previous_scr->ffcs[i];
5925 274 ffc.screen_spawned = screen;
5926
5927
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 ffc_id_t ffc_id = get_region_screen_offset(screen)*MAXFFCS + i;
5928
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 loadscr_ffc_script_ids_to_remove.erase(ffc_id);
5929
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 274 times.
274 if (previous_scr->ffcs[i].flags&ffc_scriptreset)
5930 {
5931 FFCore.reset_script_engine_data(ScriptType::FFC, ffc_id);
5932 }
5933 274 }
5934 4608 }
5935 144 }
5936
5937
1/2
✓ Branch 0 taken 37098 times.
✗ Branch 1 not taken.
1141914 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
5938
1/2
✓ Branch 0 taken 37098 times.
✗ Branch 1 not taken.
37098 int num_ffcs = base_scr->numFFC();
5939
2/2
✓ Branch 0 taken 1104816 times.
✓ Branch 1 taken 37098 times.
1141914 for (word i = 0; i < num_ffcs; i++)
5940 {
5941 1104816 base_scr->ffcs[i].screen_spawned = screen;
5942
1/2
✓ Branch 0 taken 1104816 times.
✗ Branch 1 not taken.
1104816 base_scr->ffcs[i].x += offx;
5943
1/2
✓ Branch 0 taken 1104816 times.
✗ Branch 1 not taken.
1104816 base_scr->ffcs[i].y += offy;
5944 1104816 }
5945 37098 }
5946
5947 37098 static void load_a_screen_and_layers_post(int dmap, int screen, int ldir)
5948 {
5949 37098 mapscr* base_scr = get_scr(screen);
5950 37098 int mi = mapind(cur_map, screen);
5951
5952 // Apply perm secrets, if applicable.
5953
2/2
✓ Branch 0 taken 11520 times.
✓ Branch 1 taken 25578 times.
37098 if (canPermSecret(dmap, screen))
5954 {
5955
2/2
✓ Branch 0 taken 23053 times.
✓ Branch 1 taken 2525 times.
25578 if(game->maps[mi] & mSECRET) // if special stuff done before
5956 {
5957 2525 reveal_hidden_stairs(base_scr, screen, false);
5958 2525 trigger_secrets_for_screen(TriggerSource::SecretsScreenState, base_scr, false);
5959 2525 }
5960
2/2
✓ Branch 0 taken 25575 times.
✓ Branch 1 taken 3 times.
25578 if(game->maps[mi] & mLIGHTBEAM) // if special stuff done before
5961 {
5962
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 for (int layer = 0; layer <= 6; layer++)
5963 {
5964 21 mapscr* layer_scr = get_scr_layer(screen, layer);
5965
2/2
✓ Branch 0 taken 3696 times.
✓ Branch 1 taken 21 times.
3717 for (int pos = 0; pos < 176; pos++)
5966 {
5967 3696 newcombo const* cmb = &combobuf[layer_scr->data[pos]];
5968
2/2
✓ Branch 0 taken 3693 times.
✓ Branch 1 taken 3 times.
3696 if(cmb->type == cLIGHTTARGET)
5969 {
5970
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!(cmb->usrflags&cflag1)) //Unlit version
5971 {
5972 3 layer_scr->data[pos] += 1;
5973 3 }
5974 3 }
5975 3696 }
5976 21 }
5977 3 }
5978 25578 }
5979
5980 37098 auto screen_handles = create_screen_handles(base_scr);
5981
5982 37098 int destlvl = DMaps[dmap].level;
5983 37098 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
5984 37098 toggle_gswitches_load(screen_handles);
5985
5986 37098 bool should_check_for_state_things = (screen < 0x80);
5987
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 36191 times.
37098 if (should_check_for_state_things)
5988 {
5989
2/2
✓ Branch 0 taken 35819 times.
✓ Branch 1 taken 372 times.
36191 if (game->maps[mi]&mLOCKBLOCK)
5990 372 remove_lockblocks(screen_handles);
5991
2/2
✓ Branch 0 taken 36133 times.
✓ Branch 1 taken 58 times.
36191 if (game->maps[mi]&mBOSSLOCKBLOCK)
5992 58 remove_bosslockblocks(screen_handles);
5993
2/2
✓ Branch 0 taken 36035 times.
✓ Branch 1 taken 156 times.
36191 if (game->maps[mi]&mCHEST)
5994 156 remove_chests(screen_handles);
5995
1/2
✓ Branch 0 taken 36191 times.
✗ Branch 1 not taken.
36191 if (game->maps[mi]&mLOCKEDCHEST)
5996 remove_lockedchests(screen_handles);
5997
2/2
✓ Branch 0 taken 36180 times.
✓ Branch 1 taken 11 times.
36191 if (game->maps[mi]&mBOSSCHEST)
5998 11 remove_bosschests(screen_handles);
5999
6000 36191 clear_xdoors_mi(screen_handles, mi, true);
6001 36191 clear_xstatecombos_mi(screen_handles, mi, true);
6002 36191 }
6003
6004 // check doors
6005
2/2
✓ Branch 0 taken 25577 times.
✓ Branch 1 taken 11521 times.
37098 if (isdungeon(dmap, screen))
6006 {
6007
2/2
✓ Branch 0 taken 46084 times.
✓ Branch 1 taken 11521 times.
57605 for(int32_t i=0; i<4; i++)
6008 {
6009 46084 int32_t door=base_scr->door[i];
6010
6011
5/5
✓ Branch 0 taken 5303 times.
✓ Branch 1 taken 36475 times.
✓ Branch 2 taken 2372 times.
✓ Branch 3 taken 230 times.
✓ Branch 4 taken 1704 times.
46084 switch(door)
6012 {
6013 case d1WAYSHUTTER:
6014 case dSHUTTER:
6015
3/4
✓ Branch 0 taken 1694 times.
✓ Branch 1 taken 3609 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1694 times.
5303 if ((ldir^1)==i && screen == hero_screen)
6016 {
6017 1694 base_scr->door[i]=dOPENSHUTTER;
6018 1694 }
6019
6020 5303 get_screen_state(screen).open_doors = -4;
6021 5303 break;
6022
6023 case dLOCKED:
6024
3/4
✓ Branch 0 taken 2372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1473 times.
✓ Branch 3 taken 899 times.
2372 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6025 {
6026 1473 base_scr->door[i]=dUNLOCKED;
6027 1473 }
6028
6029 2372 break;
6030
6031 case dBOSS:
6032
3/4
✓ Branch 0 taken 230 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 168 times.
230 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6033 {
6034 62 base_scr->door[i]=dOPENBOSS;
6035 62 }
6036
6037 230 break;
6038
6039 case dBOMB:
6040
3/4
✓ Branch 0 taken 1704 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1087 times.
✓ Branch 3 taken 617 times.
1704 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6041 {
6042 1087 base_scr->door[i]=dBOMBED;
6043 1087 }
6044
6045 1704 break;
6046 }
6047
6048 46084 update_door(base_scr, i, base_scr->door[i]);
6049
6050
4/4
✓ Branch 0 taken 41517 times.
✓ Branch 1 taken 4567 times.
✓ Branch 2 taken 736 times.
✓ Branch 3 taken 40781 times.
46084 if(door==dSHUTTER||door==d1WAYSHUTTER)
6051 {
6052 5303 base_scr->door[i]=door;
6053 5303 }
6054 46084 }
6055 11521 }
6056
6057
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 36961 times.
37098 if (!(base_scr->flags3 & fCYCLEONINIT))
6058 36961 return;
6059
6060
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 959 times.
1096 for (int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6061 {
6062
4/4
✓ Branch 0 taken 822 times.
✓ Branch 1 taken 137 times.
✓ Branch 2 taken 377 times.
✓ Branch 3 taken 445 times.
959 if (j<0 || base_scr->layermap[j] > 0)
6063 {
6064 514 mapscr* layer_scr = get_scr_layer(screen, j + 1);
6065
3/4
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 377 times.
514 mapscr* layerscreen= (j<0 ? base_scr : layer_scr->valid ? layer_scr :
6066 &TheMaps[(base_scr->layermap[j]-1)*MAPSCRS]+base_scr->layerscreen[j]);
6067
6068
2/2
✓ Branch 0 taken 90464 times.
✓ Branch 1 taken 514 times.
90978 for(int32_t i=0; i<176; ++i)
6069 {
6070 90464 int32_t c=layerscreen->data[i];
6071
6072 // New screen flag: Cycle Combos At Screen Init
6073
5/6
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 90399 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
90464 if(combobuf[c].nextcombo != 0 && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6074 {
6075 65 int32_t r = 0;
6076
6077
4/4
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 65 times.
149 while(combobuf[c].can_cycle() && r++ < 10)
6078 {
6079 84 newcombo const& cmb = combobuf[c];
6080 84 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6081
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6082 84 layerscreen->data[i] = cid;
6083
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 69 times.
84 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6084
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6085 84 c = layerscreen->data[i];
6086 }
6087 65 }
6088 90464 }
6089 514 }
6090 959 }
6091 37098 }
6092
6093 // Set `cur_screen` to `screen` and load new screens into temporary memory.
6094 //
6095 // Called anytime a player moves to a new screen (either via warping, scrolling, continue, starting
6096 // the game, etc...)
6097 //
6098 // Note: for regions, only the initial screen load calls this function. Simply walking between
6099 // screens in the same region does not use this, because every screen in a region is loaded into
6100 // temporary memory up front.
6101 //
6102 // If scr >= 0x80, `hero_screen` will be saved to `home_screen` and also be loaded into
6103 // `special_warp_return_scr`.
6104 //
6105 // If origin_screen_overlay is true, the old origin_scr combos will be copied to the new origin_scr combos
6106 // on all layers (but only where the new screen has a 0 combo).
6107 //
6108 // TODO: loadscr should set curdmap, but currently callers do that.
6109 35854 void loadscr(int32_t destdmap, int32_t screen, int32_t ldir, bool origin_screen_overlay, bool no_x80_dir)
6110 {
6111 35854 zapp_reporting_set_tag("screen", screen);
6112
2/2
✓ Branch 0 taken 8928 times.
✓ Branch 1 taken 26926 times.
35854 if (destdmap != -1)
6113 8928 zapp_reporting_set_tag("dmap", destdmap);
6114
6115 35854 int32_t orig_destdmap = destdmap;
6116
2/2
✓ Branch 0 taken 8928 times.
✓ Branch 1 taken 26926 times.
35854 if (destdmap < 0) destdmap = cur_dmap;
6117
6118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35854 times.
35854 if (replay_is_active())
6119 {
6120
1/2
✓ Branch 0 taken 35854 times.
✗ Branch 1 not taken.
35854 if (replay_get_mode() == ReplayMode::ManualTakeover)
6121 replay_stop_manual_takeover();
6122
6123
2/2
✓ Branch 0 taken 26926 times.
✓ Branch 1 taken 8928 times.
35854 if (orig_destdmap != -1)
6124 {
6125
2/2
✓ Branch 0 taken 7857 times.
✓ Branch 1 taken 1071 times.
8928 if (strlen(DMaps[orig_destdmap].name) > 0)
6126 {
6127
1/2
✓ Branch 0 taken 7857 times.
✗ Branch 1 not taken.
7857 replay_step_comment(fmt::format("dmap={} {}", orig_destdmap, DMaps[orig_destdmap].name));
6128 7857 }
6129 else
6130 {
6131
1/2
✓ Branch 0 taken 1071 times.
✗ Branch 1 not taken.
1071 replay_step_comment(fmt::format("dmap={}", orig_destdmap));
6132 }
6133 8928 }
6134 35854 replay_step_comment_loadscr(screen);
6135
6136 // Reset the rngs and frame count so that recording steps can be modified without impacting
6137 // behavior of later screens.
6138 35854 replay_sync_rng();
6139 35854 }
6140
6141
2/2
✓ Branch 0 taken 1707536 times.
✓ Branch 1 taken 35854 times.
1743390 for (auto& state : get_screen_states())
6142 1707536 state.second.triggered_secrets = false;
6143 35854 slopes.clear();
6144 35854 Hero.clear_platform_ffc();
6145 35854 timeExitAllGenscript(GENSCR_ST_CHANGE_SCREEN);
6146 35854 clear_darkroom_bitmaps();
6147 35854 msgscr = nullptr;
6148
6149
2/2
✓ Branch 0 taken 50391860 times.
✓ Branch 1 taken 35854 times.
50427714 for (word x=0; x<animated_combos; x++)
6150 {
6151
2/2
✓ Branch 0 taken 20919990 times.
✓ Branch 1 taken 29471870 times.
50391860 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6152 {
6153 20919990 combobuf[animated_combo_table4[x][0]].aclk = 0;
6154 20919990 }
6155 50391860 }
6156 35854 reset_combo_animations2();
6157 35854 region_is_lit = false;
6158
6159 // Legacy features (combo and ffc overlays) may need the previous origin screens during loading
6160 // of the new ones.
6161 35854 bool origin_ffc_overlay = false;
6162
2/2
✓ Branch 0 taken 34717 times.
✓ Branch 1 taken 1137 times.
35854 if (origin_scr)
6163 {
6164
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 34715 times.
34717 if (!(origin_scr->flags5&fNOFFCARRYOVER))
6165 {
6166 34715 int c = origin_scr->numFFC();
6167
2/2
✓ Branch 0 taken 34571 times.
✓ Branch 1 taken 1038879 times.
1073450 for (int i = 0; i < c; i++)
6168 {
6169
2/2
✓ Branch 0 taken 1038735 times.
✓ Branch 1 taken 144 times.
1038879 if (origin_scr->ffcs[i].flags&ffc_carryover)
6170 {
6171 144 origin_ffc_overlay = true;
6172 144 break;
6173 }
6174 1038735 }
6175 34715 }
6176
6177
3/4
✓ Branch 0 taken 34717 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144 times.
✓ Branch 3 taken 34573 times.
34717 if (origin_screen_overlay || origin_ffc_overlay)
6178 {
6179
2/2
✓ Branch 0 taken 1008 times.
✓ Branch 1 taken 144 times.
1152 for (int i = 0; i <= 6; i++)
6180 {
6181 1008 mapscr* prev_scr = get_scr_layer(cur_screen, i);
6182
1/2
✓ Branch 0 taken 1008 times.
✗ Branch 1 not taken.
1008 if (prev_scr)
6183 1008 prev_origin_scrs[i] = *prev_scr;
6184 else
6185 prev_origin_scrs[i] = {};
6186 1008 }
6187 144 }
6188 34717 }
6189
6190 // Based on origin_ffc_overlay, some ffc scripts don't get reset. This set starts with all of
6191 // them, but scripts that need their data to persist will be removed.
6192 35854 loadscr_ffc_script_ids_to_remove.clear();
6193
2/2
✓ Branch 0 taken 74698175 times.
✓ Branch 1 taken 35854 times.
74734029 for (auto& key : scriptEngineDatas | std::views::keys)
6194 {
6195
2/2
✓ Branch 0 taken 73576270 times.
✓ Branch 1 taken 1121905 times.
74698175 if (key.first == ScriptType::FFC)
6196 1121905 loadscr_ffc_script_ids_to_remove.insert(key.second);
6197 }
6198
6199 35854 load_region(destdmap, screen);
6200
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 34947 times.
35854 home_screen = screen >= 0x80 ? hero_screen : cur_screen;
6201 35854 hero_screen = screen;
6202
6203 35854 cpos_clear_all();
6204 35854 FFCore.destroyScriptableObjectsOfType(ScriptType::Screen);
6205 35854 FFCore.clear_combo_scripts();
6206
6207
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 35690 times.
35854 if (is_in_scrolling_region())
6208 {
6209
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6210 {
6211
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6212 {
6213
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool screen_overlay = origin_screen_overlay && screen == cur_screen;
6214
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool ffc_overlay = origin_ffc_overlay && screen == cur_screen;
6215 1408 load_a_screen_and_layers_init(destdmap, screen, ldir, screen_overlay, ffc_overlay);
6216 1408 }
6217 20992 }
6218 164 }
6219 else
6220 {
6221 35690 load_a_screen_and_layers_init(destdmap, screen, ldir, origin_screen_overlay, origin_ffc_overlay);
6222 }
6223
6224 35854 prepare_current_region_handles();
6225
6226
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 35690 times.
35854 if (is_in_scrolling_region())
6227 {
6228
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6229 {
6230
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6231 {
6232 1408 load_a_screen_and_layers_post(destdmap, screen, ldir);
6233 1408 }
6234 20992 }
6235 164 }
6236 else
6237 {
6238 35690 load_a_screen_and_layers_post(destdmap, screen, ldir);
6239 }
6240
6241 // If on a special screen, load the screen the player is currently on (home_screen) into special_warp_return_scr.
6242
2/2
✓ Branch 0 taken 34947 times.
✓ Branch 1 taken 907 times.
35854 if (screen >= 0x80)
6243
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 431 times.
907 loadscr_old(orig_destdmap, home_screen, no_x80_dir ? -1 : ldir, origin_screen_overlay);
6244
6245 35854 update_slope_comboposes();
6246 35854 cpos_force_update();
6247 35854 trig_trigger_groups();
6248
6249
2/2
✓ Branch 0 taken 1121631 times.
✓ Branch 1 taken 35854 times.
1157485 for (int index : loadscr_ffc_script_ids_to_remove)
6250 {
6251 1121631 FFCore.destroyScriptableObject(ScriptType::FFC, index);
6252 }
6253
6254 // "extended height mode" includes the top 56 pixels as part of the visible mapscr viewport,
6255 // allowing for regions to display 4 more rows of combos (as many as ALTTP does). This part of
6256 // screen is normally reserved for the passive subscreen, but in this mode mapscr combos are drawn below it.
6257 // It is up to the quest designer to make their subscreen be actually transparent.
6258 //
6259 // When not in "extended height mode" (otherwise 56 is 0):
6260 // - playing_field_offset: 56, but changes during earthquakes
6261 // - original_playing_field_offset: always 56
6262 //
6263 // These values are used to adjust where things are drawn on screen to account for the passive subscreen. Examples:
6264 // - yofs of sprites
6265 // - bitmap y offsets in draw_screen
6266 // - drawing offsets for putscr, do_layer
6267 // - drawing offsets for various calls to overtile16 (see bomb weapon explosion)
6268 // - lots more
6269 //
6270 // TODO: consider refactor of yofs, make yofs start as 0 by default and add playing_field_offset at draw time?
6271
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 35712 times.
35854 if (is_extended_height_mode())
6272 {
6273 142 playing_field_offset = 0;
6274 142 original_playing_field_offset = 0;
6275 // A few sprites exist as globals, so we must manually reset them.
6276 142 Hero.yofs = 0;
6277 142 mblock2.yofs = 0;
6278 142 }
6279 else
6280 {
6281 35712 mblock2.yofs = Hero.yofs = playing_field_offset = 56;
6282 35712 original_playing_field_offset = 56;
6283 }
6284 35854 is_any_room_dark = is_any_dark();
6285
6286 35854 game->load_portal();
6287 35854 throwGenScriptEvent(GENSCR_EVENT_CHANGE_SCREEN);
6288
3/4
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 35819 times.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
35854 if (Hero.lift_wpn && get_qr(qr_CARRYABLE_NO_ACROSS_SCREEN))
6289 {
6290 delete Hero.lift_wpn;
6291 Hero.lift_wpn = nullptr;
6292 }
6293
6294 35854 enemy_spawning_has_checked_been_here = false;
6295 35854 markBmap(-1, hero_screen);
6296 35854 Hero.maybe_begin_advanced_maze();
6297 35854 }
6298
6299 // Don't use this directly! Use `loadscr` instead.
6300 907 void loadscr_old(int32_t destdmap, int32_t screen,int32_t ldir,bool overlay)
6301 {
6302
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int32_t destlvl = DMaps[destdmap < 0 ? cur_dmap : destdmap].level;
6303
6304 907 mapscr previous_scr = *special_warp_return_scr;
6305 907 mapscr* scr = special_warp_return_scr;
6306
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 const mapscr* source = get_canonical_scr(cur_map, screen);
6307
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 *scr = *source;
6308
6309
2/2
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 907 times.
6349 for (int i = 1; i <= 6; i++)
6310 {
6311
2/2
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 5059 times.
5442 if (scr->layermap[i-1] > 0)
6312
2/4
✓ Branch 0 taken 383 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 383 times.
✗ Branch 3 not taken.
383 special_warp_return_scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6313 else
6314 5059 special_warp_return_scrs[i] = {};
6315 5442 }
6316
6317 907 scr->valid |= mVALID; //layer 0 is always valid
6318
6319
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 907 times.
907 if ( source->script > 0 )
6320 {
6321 scr->script = source->script;
6322 for ( int32_t q = 0; q < 8; q++ )
6323 {
6324 scr->screeninitd[q] = source->screeninitd[q];
6325 }
6326 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6327 }
6328 else
6329 {
6330 907 scr->script = 0;
6331 }
6332
6333
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 if(overlay)
6334 {
6335 for(int32_t c=0; c< 176; ++c)
6336 {
6337 if(scr->data[c]==0)
6338 {
6339 scr->data[c]=previous_scr.data[c];
6340 scr->sflag[c]=previous_scr.sflag[c];
6341 scr->cset[c]=previous_scr.cset[c];
6342 }
6343 }
6344
6345 for(int32_t i=0; i<6; i++)
6346 {
6347 if(previous_scr.layermap[i]>0 && scr->layermap[i]>0)
6348 {
6349 int32_t lm = (scr->layermap[i]-1)*MAPSCRS+scr->layerscreen[i];
6350 int32_t fm = (previous_scr.layermap[i]-1)*MAPSCRS+previous_scr.layerscreen[i];
6351
6352 for(int32_t c=0; c< 176; ++c)
6353 {
6354 if(TheMaps[lm].data[c]==0)
6355 {
6356 TheMaps[lm].data[c] = TheMaps[fm].data[c];
6357 TheMaps[lm].sflag[c] = TheMaps[fm].sflag[c];
6358 TheMaps[lm].cset[c] = TheMaps[fm].cset[c];
6359 }
6360 }
6361 }
6362 }
6363 }
6364
6365
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
29900 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6366
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int c = scr->numFFC();
6367
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 28993 times.
29900 for (word i = 0; i < c; i++)
6368 {
6369 28993 scr->ffcs[i].screen_spawned = screen;
6370
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].x += offx;
6371
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].y += offy;
6372 28993 }
6373
6374 907 int mi = mapind(cur_map, screen);
6375
6376 // Apply perm secrets, if applicable.
6377
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if(canPermSecret(destdmap,screen))
6378 {
6379
3/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 332 times.
536 if(game->maps[mi]&mSECRET) // if special stuff done before
6380 {
6381
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 reveal_hidden_stairs(scr, screen, false);
6382
6383
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
6384
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 get_screen_state(special_warp_return_scr->screen).triggered_secrets = true;
6385 204 bool do_replay_comment = true;
6386 204 bool from_active_screen = false;
6387
2/4
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✗ Branch 3 not taken.
204 trigger_secrets_for_screen_internal(create_screen_handles(special_warp_return_scr), from_active_screen, false, -1, do_replay_comment);
6388 204 }
6389
2/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✗ Branch 3 not taken.
536 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6390 {
6391 for (int layer = 0; layer <= 6; layer++)
6392 {
6393 mapscr* tscr = &special_warp_return_scrs[layer];
6394 for (int pos = 0; pos < 176; pos++)
6395 {
6396 newcombo const* cmb = &combobuf[tscr->data[pos]];
6397 if(cmb->type == cLIGHTTARGET)
6398 {
6399 if(!(cmb->usrflags&cflag1)) //Unlit version
6400 {
6401 tscr->data[pos] += 1;
6402 }
6403 }
6404 }
6405 }
6406 }
6407 536 }
6408
6409 screen_handles_t screen_handles;
6410
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 6349 times.
7256 for (int i = 0; i <= 6; i++)
6411
3/4
✓ Branch 0 taken 6349 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1289 times.
✓ Branch 3 taken 5060 times.
6349 screen_handles[i] = {scr, special_warp_return_scrs[i].is_valid() ? &special_warp_return_scrs[i] : nullptr, screen, i};
6412
6413
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 907 times.
✗ Branch 3 not taken.
907 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6414
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 toggle_gswitches_load(screen_handles);
6415
6416
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 902 times.
907 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6417 {
6418
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 remove_lockblocks(screen_handles);
6419 5 }
6420
6421
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 906 times.
907 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6422 {
6423
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6424 1 }
6425
6426
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mCHEST) // if special stuff done before
6427 {
6428 remove_chests(screen_handles);
6429 }
6430
6431
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6432 {
6433 remove_lockedchests(screen_handles);
6434 }
6435
6436
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6437 {
6438 remove_bosschests(screen_handles);
6439 }
6440
6441
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xdoors(screen_handles, true);
6442
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xstatecombos(screen_handles, true);
6443
6444 // check doors
6445
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 371 times.
✓ Branch 3 taken 536 times.
907 if (isdungeon(destdmap, screen))
6446 {
6447
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 371 times.
1855 for(int32_t i=0; i<4; i++)
6448 {
6449 1484 int32_t door=scr->door[i];
6450
6451
4/4
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 89 times.
✓ Branch 3 taken 1295 times.
1484 switch(door)
6452 {
6453 case d1WAYSHUTTER:
6454 case dSHUTTER:
6455
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1295 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1295 if ((ldir^1)==i && screen == home_screen)
6456 {
6457 scr->door[i]=dOPENSHUTTER;
6458 }
6459
6460
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 1190 times.
1295 get_screen_state(screen).open_doors = -4;
6461 105 break;
6462
6463 case dLOCKED:
6464
3/4
✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✓ Branch 3 taken 11 times.
91 if(game->maps[mi]&(mDOOR_UP<<i))
6465 {
6466 80 scr->door[i]=dUNLOCKED;
6467 80 }
6468
6469 91 break;
6470
6471 case dBOSS:
6472
3/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 4 times.
9 if(game->maps[mi]&(mDOOR_UP<<i))
6473 {
6474 5 scr->door[i]=dOPENBOSS;
6475 5 }
6476
6477 9 break;
6478
6479 case dBOMB:
6480
3/4
✓ Branch 0 taken 89 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 38 times.
89 if(game->maps[mi]&(mDOOR_UP<<i))
6481 {
6482 51 scr->door[i]=dBOMBED;
6483 51 }
6484
6485 89 break;
6486 }
6487
6488
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 1190 times.
294 update_door(scr, i, scr->door[i]);
6489
6490
4/4
✓ Branch 0 taken 1390 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 1379 times.
1484 if(door==dSHUTTER||door==d1WAYSHUTTER)
6491 {
6492 105 scr->door[i]=door;
6493 105 }
6494 1484 }
6495 371 }
6496
6497
2/2
✓ Branch 0 taken 6915 times.
✓ Branch 1 taken 549 times.
7256 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6498 {
6499
4/4
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 1473 times.
✓ Branch 2 taken 2763 times.
✓ Branch 3 taken 2679 times.
6915 if (j<0 || scr->layermap[j] > 0)
6500 {
6501
4/4
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 383 times.
✓ Branch 2 taken 382 times.
✓ Branch 3 taken 1 times.
4236 mapscr *layerscreen= (j<0 ? scr : special_warp_return_scrs[j+1].valid ? &special_warp_return_scrs[j+1] :
6502 1 &TheMaps[(scr->layermap[j]-1)*MAPSCRS]+scr->layerscreen[j]);
6503
6504
2/2
✓ Branch 0 taken 224660 times.
✓ Branch 1 taken 3670 times.
228330 for(int32_t i=0; i<176; ++i)
6505 {
6506 224660 int32_t c=layerscreen->data[i];
6507
6508 // New screen flag: Cycle Combos At Screen Init
6509
5/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 224654 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 2380 times.
✓ Branch 7 taken 2380 times.
224660 if(combobuf[c].nextcombo != 0 && (scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6510 {
6511 2380 int32_t r = 0;
6512
6513
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2380 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2380 while(combobuf[c].can_cycle() && r++ < 10)
6514 {
6515 newcombo const& cmb = combobuf[c];
6516 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6517 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6518 layerscreen->data[i] = cid;
6519 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6520 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6521 c = layerscreen->data[i];
6522 }
6523 }
6524 227040 }
6525 3670 }
6526 6349 }
6527 5309 }
6528
6529 // Load screen (and layers). Unlike loadscr, this doesn't load to the global temporary_screens, but
6530 // instead returns an array of mapscr.
6531 // Used to draw/save the map.
6532 45680 std::array<mapscr, 7> loadscr2(int32_t screen)
6533 {
6534 45680 std::array<mapscr, 7> scrs;
6535 45680 mapscr* scr = &scrs[0];
6536
6537
2/2
✓ Branch 0 taken 64716181 times.
✓ Branch 1 taken 45680 times.
64761861 for(word x=0; x<animated_combos; x++)
6538 {
6539
2/2
✓ Branch 0 taken 31963685 times.
✓ Branch 1 taken 32752496 times.
64716181 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6540 {
6541 32752496 combobuf[animated_combo_table4[x][0]].aclk=0;
6542 32752496 }
6543 64716181 }
6544
6545
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 const mapscr* source = get_canonical_scr(cur_map, screen);
6546
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if (!source->is_valid())
6547 {
6548 scrs[0].valid = 0;
6549 return scrs;
6550 }
6551
6552
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 *scr = *get_canonical_scr(cur_map, screen);
6553
2/2
✓ Branch 0 taken 274080 times.
✓ Branch 1 taken 45680 times.
319760 for (int i = 1; i <= 6; i++)
6554 {
6555
2/2
✓ Branch 0 taken 64814 times.
✓ Branch 1 taken 209266 times.
274080 if (scr->layermap[i-1] > 0)
6556
2/4
✓ Branch 0 taken 64814 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 64814 times.
✗ Branch 3 not taken.
64814 scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6557 else
6558 209266 scrs[i] = {};
6559 274080 }
6560
6561 screen_handles_t screen_handles;
6562
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 319760 times.
365440 for (int i = 0; i < 7; i++)
6563
3/4
✓ Branch 0 taken 319760 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103790 times.
✓ Branch 3 taken 215970 times.
319760 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
6564
6565 45680 int mi = mapind(cur_map, screen);
6566
6567
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45626 times.
✓ Branch 3 taken 54 times.
45680 if(canPermSecret(-1,screen))
6568 {
6569
3/4
✓ Branch 0 taken 45626 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5730 times.
✓ Branch 3 taken 39896 times.
45626 if(game->maps[mi]&mSECRET) // if special stuff done before
6570 {
6571
1/2
✓ Branch 0 taken 5730 times.
✗ Branch 1 not taken.
5730 reveal_hidden_stairs(scr, screen, false);
6572 5730 bool from_active_screen = false;
6573 5730 bool do_replay_comment = true;
6574
1/2
✓ Branch 0 taken 5730 times.
✗ Branch 1 not taken.
5730 trigger_secrets_for_screen_internal(screen_handles, from_active_screen, false, -1, do_replay_comment);
6575 5730 }
6576
3/4
✓ Branch 0 taken 45626 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45609 times.
✓ Branch 3 taken 17 times.
45626 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6577 {
6578
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 17 times.
136 for (int layer = 0; layer <= 6; layer++)
6579 {
6580 119 mapscr* tscr = &scrs[layer];
6581
2/2
✓ Branch 0 taken 20944 times.
✓ Branch 1 taken 119 times.
21063 for (int pos = 0; pos < 176; pos++)
6582 {
6583 20944 newcombo const* cmb = &combobuf[tscr->data[pos]];
6584
2/2
✓ Branch 0 taken 20927 times.
✓ Branch 1 taken 17 times.
20944 if(cmb->type == cLIGHTTARGET)
6585 {
6586
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if(!(cmb->usrflags&cflag1)) //Unlit version
6587 {
6588 17 tscr->data[pos] += 1;
6589 17 }
6590 17 }
6591 20944 }
6592 119 }
6593 17 }
6594 45626 }
6595
6596
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 233 times.
✓ Branch 3 taken 45447 times.
45680 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6597 {
6598
1/2
✓ Branch 0 taken 233 times.
✗ Branch 1 not taken.
233 remove_lockblocks(screen_handles);
6599 233 }
6600
6601
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 45679 times.
45680 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6602 {
6603
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6604 1 }
6605
6606
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 101 times.
✓ Branch 3 taken 45579 times.
45680 if(game->maps[mi]&mCHEST) // if special stuff done before
6607 {
6608
1/2
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
101 remove_chests(screen_handles);
6609 101 }
6610
6611
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 45656 times.
45680 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6612 {
6613
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 remove_lockedchests(screen_handles);
6614 24 }
6615
6616
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45680 times.
45680 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6617 {
6618 remove_bosschests(screen_handles);
6619 }
6620
6621
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 clear_xdoors(screen_handles);
6622
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 clear_xstatecombos(screen_handles);
6623
6624 // check doors
6625
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
✓ Branch 3 taken 45626 times.
45680 if (isdungeon(screen))
6626 {
6627
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 54 times.
270 for(int32_t i=0; i<4; i++)
6628 {
6629 216 int32_t door=scr->door[i];
6630 216 bool putit=true;
6631
6632
4/5
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 61 times.
✓ Branch 4 taken 139 times.
216 switch(door)
6633 {
6634 case d1WAYSHUTTER:
6635 case dSHUTTER:
6636 61 break;
6637
6638 case dLOCKED:
6639
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if(game->maps[mi]&(mDOOR_UP<<i))
6640 {
6641 12 scr->door[i]=dUNLOCKED;
6642 12 }
6643
6644 12 break;
6645
6646 case dBOSS:
6647
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if(game->maps[mi]&(mDOOR_UP<<i))
6648 {
6649 scr->door[i]=dOPENBOSS;
6650 }
6651
6652 4 break;
6653
6654 case dBOMB:
6655 if(game->maps[mi]&(mDOOR_UP<<i))
6656 {
6657 scr->door[i]=dBOMBED;
6658 }
6659
6660 break;
6661 }
6662
6663
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if(putit)
6664 {
6665
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 putdoor(scr, scrollbuf, i, scr->door[i], false);
6666 216 }
6667
6668
3/4
✓ Branch 0 taken 155 times.
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
216 if(door==dSHUTTER||door==d1WAYSHUTTER)
6669 {
6670 61 scr->door[i]=door;
6671 61 }
6672 216 }
6673 54 }
6674
6675
2/2
✓ Branch 0 taken 319760 times.
✓ Branch 1 taken 45680 times.
365440 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6676 {
6677
4/4
✓ Branch 0 taken 274080 times.
✓ Branch 1 taken 45680 times.
✓ Branch 2 taken 64814 times.
✓ Branch 3 taken 209266 times.
319760 if (j < 0 || scr->layermap[j] > 0)
6678 {
6679
2/2
✓ Branch 0 taken 64814 times.
✓ Branch 1 taken 45680 times.
110494 mapscr *layerscreen= (j<0 ? scr
6680 64814 : &(TheMaps[(scr->layermap[j]-1)*MAPSCRS+scr->layerscreen[j]]));
6681
6682
2/2
✓ Branch 0 taken 19446944 times.
✓ Branch 1 taken 110494 times.
19557438 for(int32_t i=0; i<176; ++i)
6683 {
6684 19446944 int32_t c=layerscreen->data[i];
6685
6686 // New screen flag: Cycle Combos At Screen Init
6687
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 19446944 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
19446944 if((scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6688 {
6689 int32_t r = 0;
6690
6691 while(combobuf[c].can_cycle() && r++ < 10)
6692 {
6693 newcombo const& cmb = combobuf[c];
6694 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6695 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6696 layerscreen->data[i] = cid;
6697 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6698 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6699 c = layerscreen->data[i];
6700 }
6701 }
6702 19446944 }
6703 110494 }
6704 319760 }
6705
6706 45680 return scrs;
6707
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 }
6708
6709 19016051 void putscr(mapscr* scr, BITMAP* dest, int32_t x, int32_t y)
6710 {
6711 // This is a bogus value while screenscrolling == true, but that's ok
6712 // because it is only used to calculate the rpos, and during screenscrolling
6713 // only the modulus to get pos (draw_cmb_pos does RPOS_TO_POS) is needed, which
6714 // is always the same no matter the value of scr.
6715 19016051 int screen = get_screen_for_world_xy(x, y);
6716
6717 19016051 x -= viewport.x;
6718 19016051 y -= viewport.y;
6719
6720
3/6
✓ Branch 0 taken 19016051 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19016051 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 19016051 times.
19016051 if (!scr->is_valid()||!show_layers[0]||scr->hidelayers & 1)
6721 {
6722 rectfill(dest,x,y,x+255,y+175,0);
6723 return;
6724 }
6725
6726 37903193 bool over = XOR(scr->flags7&fLAYER2BG,DMaps[cur_dmap].flags&dmfLAYER2BG)
6727
2/2
✓ Branch 0 taken 128909 times.
✓ Branch 1 taken 18887142 times.
19016051 || XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG);
6728
6729 int start_x, end_x, start_y, end_y;
6730 19016051 get_bounds_for_draw_cmb_calls(dest, x, y, start_x, end_x, start_y, end_y);
6731
2/2
✓ Branch 0 taken 19016051 times.
✓ Branch 1 taken 202549048 times.
221565099 for (int cy = start_y; cy < end_y; cy++)
6732 {
6733
2/2
✓ Branch 0 taken 3075834962 times.
✓ Branch 1 taken 202549048 times.
3278384010 for (int cx = start_x; cx < end_x; cx++)
6734 {
6735 3075834962 int i = cx + cy*16;
6736
2/2
✓ Branch 0 taken 357850966 times.
✓ Branch 1 taken 2717983996 times.
3075834962 auto rpos = screenscrolling ? rpos_t::None : POS_TO_RPOS(i, screen);
6737 3075834962 draw_cmb_pos(dest, x + cx*16, y + cy*16, rpos, scr->data[i], scr->cset[i], 0, over, false);
6738 3075834962 }
6739 202549048 }
6740 19016051 }
6741
6742 15539765 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y)
6743 {
6744
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539765 times.
15539765 if (!show_layers[0])
6745 {
6746 return;
6747 }
6748
6749 15539765 x -= viewport.x;
6750 15539765 y -= viewport.y;
6751
6752
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539765 times.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
6753 15676083 mapscr* scr = screen_handles[0].base_scr;
6754
1/2
✓ Branch 0 taken 15676083 times.
✗ Branch 1 not taken.
15676083 if (!scr->is_valid())
6755 return;
6756
6757
2/2
✓ Branch 0 taken 123411 times.
✓ Branch 1 taken 15552672 times.
15676083 if(scr->door[0]==dBOMBED)
6758 {
6759 123411 over_door(scr, dest, 39, up, offx+x, offy+y);
6760 123411 }
6761
6762
2/2
✓ Branch 0 taken 143109 times.
✓ Branch 1 taken 15532974 times.
15676083 if(scr->door[1]==dBOMBED)
6763 {
6764 143109 over_door(scr, dest, 135, down, offx+x, offy+y);
6765 143109 }
6766
6767
2/2
✓ Branch 0 taken 155862 times.
✓ Branch 1 taken 15520221 times.
15676083 if(scr->door[2]==dBOMBED)
6768 {
6769 155862 over_door(scr, dest, 66, left, offx+x, offy+y);
6770 155862 }
6771
6772
2/2
✓ Branch 0 taken 132289 times.
✓ Branch 1 taken 15543794 times.
15676083 if(scr->door[3]==dBOMBED)
6773 {
6774 132289 over_door(scr, dest, 77, right, offx+x, offy+y);
6775 132289 }
6776 15676083 });
6777 15539765 }
6778
6779 3339968 void putscrdoors(mapscr* scr, BITMAP *dest, int32_t x, int32_t y)
6780 {
6781
2/4
✓ Branch 0 taken 3339968 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3339968 times.
✗ Branch 3 not taken.
3339968 if (!scr->is_valid() || !show_layers[0])
6782 return;
6783
6784 3339968 x -= viewport.x;
6785 3339968 y -= viewport.y;
6786
6787
2/2
✓ Branch 0 taken 37656 times.
✓ Branch 1 taken 3302312 times.
3339968 if(scr->door[0]==dBOMBED)
6788 {
6789 37656 over_door(scr,dest,39,up,x,y);
6790 37656 }
6791
6792
2/2
✓ Branch 0 taken 36495 times.
✓ Branch 1 taken 3303473 times.
3339968 if(scr->door[1]==dBOMBED)
6793 {
6794 36495 over_door(scr,dest,135,down,x,y);
6795 36495 }
6796
6797
2/2
✓ Branch 0 taken 40440 times.
✓ Branch 1 taken 3299528 times.
3339968 if(scr->door[2]==dBOMBED)
6798 {
6799 40440 over_door(scr,dest,66,left,x,y);
6800 40440 }
6801
6802
2/2
✓ Branch 0 taken 37063 times.
✓ Branch 1 taken 3302905 times.
3339968 if(scr->door[3]==dBOMBED)
6803 {
6804 37063 over_door(scr,dest,77,right,x,y);
6805 37063 }
6806 3339968 }
6807 232437410 static inline bool standing_on_z(newcombo const& cmb, zfix const& standing_z_state)
6808 {
6809 232437410 zfix cmb_z, cmb_z_step;
6810
4/4
✓ Branch 0 taken 92789 times.
✓ Branch 1 taken 232344621 times.
✓ Branch 2 taken 88819 times.
✓ Branch 3 taken 3970 times.
232437410 if(cmb.type == cCSWITCHBLOCK && (cmb.usrflags & cflag9))
6811 {
6812 3970 cmb_z = zslongToFix(cmb.attributes[2]);
6813
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3970 times.
3970 cmb_z_step = zslongToFix(zc_max(0,cmb.attributes[3]));
6814 3970 }
6815
2/2
✓ Branch 0 taken 1983 times.
✓ Branch 1 taken 232431457 times.
232433440 else if(cmb.genflags & cflag3)
6816 {
6817 1983 cmb_z = cmb.z_height;
6818
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1983 times.
1983 cmb_z_step = zc_max(0_zf,cmb.z_step_height);
6819 1983 }
6820 232431457 else return false;
6821
6822
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5953 times.
✓ Branch 2 taken 4804 times.
✓ Branch 3 taken 1149 times.
5953 return (standing_z_state < 0 || (cmb_z>0 && (cmb_z - cmb_z_step) <= standing_z_state));
6823 232437410 }
6824 56117558 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt)
6825 {
6826 56117558 return _walkflag(zx,zy,cnt,0_zf);
6827 }
6828
6829 132920561 bool _walkflag_new(const mapscr* s0, const mapscr* s1, const mapscr* s2, zfix_round zx, zfix_round zy, zfix const& standing_z_state, bool is_temp_screens)
6830 {
6831 132920561 int x = zx.getRound(), y = zy.getRound();
6832 132920561 int pos = COMBOPOS(x % 256, y % 176);
6833 132920561 const newcombo& c = combobuf[s0->data[pos]];
6834 132920561 const newcombo& c1 = combobuf[s1->data[pos]];
6835 132920561 const newcombo& c2 = combobuf[s2->data[pos]];
6836
4/4
✓ Branch 0 taken 130925120 times.
✓ Branch 1 taken 1995441 times.
✓ Branch 2 taken 130915660 times.
✓ Branch 3 taken 9460 times.
266043410 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
6837
4/4
✓ Branch 0 taken 101153 times.
✓ Branch 1 taken 131016795 times.
✓ Branch 2 taken 2101809 times.
✓ Branch 3 taken 4245 times.
132920561 (iswater_type(c2.type))) && DRIEDLAKE);
6838 133122849 int32_t b=1;
6839
2/2
✓ Branch 0 taken 65628846 times.
✓ Branch 1 taken 67494003 times.
133122849 if(x&8) b<<=2;
6840
2/2
✓ Branch 0 taken 62187457 times.
✓ Branch 1 taken 70935392 times.
133122849 if(y&8) b<<=1;
6841
6842 133122849 int32_t cwalkflag = c.walk;
6843
4/4
✓ Branch 0 taken 133021705 times.
✓ Branch 1 taken 101144 times.
✓ Branch 2 taken 133021541 times.
✓ Branch 3 taken 164 times.
133122849 if(is_temp_screens && standing_on_z(c,standing_z_state)) cwalkflag &= (c.walk>>4)^0xF;
6844
8/10
✓ Branch 0 taken 50572 times.
✓ Branch 1 taken 133072113 times.
✓ Branch 2 taken 2096585 times.
✓ Branch 3 taken 2046013 times.
✓ Branch 4 taken 2096585 times.
✓ Branch 5 taken 133021541 times.
✓ Branch 6 taken 2096585 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2096585 times.
✗ Branch 9 not taken.
133122685 else if ((c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) || (iswater_type(c.type) && ((c.walk>>4)&b) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
6845
2/2
✓ Branch 0 taken 63476780 times.
✓ Branch 1 taken 69544925 times.
133021705 if (s1 != s0)
6846 {
6847
3/4
✓ Branch 0 taken 69544925 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 69544307 times.
✓ Branch 3 taken 618 times.
69544925 if(is_temp_screens && standing_on_z(c1,standing_z_state)) cwalkflag &= (c1.walk>>4)^0xF;
6848
4/10
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 69532578 times.
✓ Branch 2 taken 11729 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11729 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
69544307 else if ((iswater_type(c1.type) && ((c1.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_1) && !((c1.usrflags&cflag3) || (c1.usrflags&cflag4)))) cwalkflag &= c1.walk;
6849
2/2
✓ Branch 0 taken 62906 times.
✓ Branch 1 taken 69481401 times.
69544307 else if (c1.type == cBRIDGE)
6850 {
6851
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62906 times.
62906 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
6852 {
6853 62906 int efflag = (c1.walk & 0xF0)>>4;
6854 62906 int newsolid = (c1.walk & 0xF);
6855 62906 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
6856 62906 }
6857 else cwalkflag &= c1.walk;
6858 62906 }
6859
3/8
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 69469672 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11729 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
69481401 else if ((iswater_type(c1.type) && get_qr(qr_WATER_ON_LAYER_1) && ((c1.usrflags&cflag3) || (c1.usrflags&cflag4)) && ((c1.walk>>4)&b))) cwalkflag = 0;
6860 69481401 else cwalkflag |= c1.walk;
6861 69544925 }
6862
2/2
✓ Branch 0 taken 103150925 times.
✓ Branch 1 taken 29870780 times.
133021705 if (s2 != s0)
6863 {
6864
2/4
✓ Branch 0 taken 29870780 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29870780 times.
✗ Branch 3 not taken.
29870780 if(is_temp_screens && standing_on_z(c2,standing_z_state)) cwalkflag &= (c2.walk>>4)^0xF;
6865
4/10
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 29868626 times.
✓ Branch 2 taken 2154 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2154 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
29870780 else if ((iswater_type(c2.type) && ((c2.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_2) && !((c2.usrflags&cflag3) || (c2.usrflags&cflag4)))) cwalkflag &= c2.walk;
6866
2/2
✓ Branch 0 taken 4447 times.
✓ Branch 1 taken 29866333 times.
29870780 else if (c2.type == cBRIDGE)
6867 {
6868
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4447 times.
4447 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
6869 {
6870 4447 int efflag = (c2.walk & 0xF0)>>4;
6871 4447 int newsolid = (c2.walk & 0xF);
6872 4447 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
6873 4447 }
6874 else cwalkflag &= c2.walk;
6875 4447 }
6876
3/8
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 29864179 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2154 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
29866333 else if ((iswater_type(c2.type) && get_qr(qr_WATER_ON_LAYER_2) && ((c2.usrflags&cflag3) || (c2.usrflags&cflag4))) && ((c2.walk>>4)&b)) cwalkflag = 0;
6877 29866333 else cwalkflag |= c2.walk;
6878 29870780 }
6879
6880
4/4
✓ Branch 0 taken 29568194 times.
✓ Branch 1 taken 103453511 times.
✓ Branch 2 taken 948 times.
✓ Branch 3 taken 29567246 times.
133021705 if((cwalkflag&b) && !dried)
6881 29567246 return true;
6882
6883
3/4
✓ Branch 0 taken 103454459 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103438048 times.
✓ Branch 3 taken 16411 times.
103454459 if (is_temp_screens && collide_object(zx, zy, 0.0001_zf, 0.0001_zf)) return true;
6884
6885 103438048 return false;
6886 133021705 }
6887
6888 // Returns true if the combo at viewport position x,y is solid. Looks at a combo's quadrant walkablity flags.
6889 133021705 static bool _walkflag_new(zfix_round zx, zfix_round zy, zfix const& standing_z_state)
6890 {
6891 133021705 int x = zx.getRound(), y = zy.getRound();
6892 133021705 mapscr* s0 = get_scr_for_world_xy_layer(x, y, 0);
6893 133021705 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
6894 133021705 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
6895
2/2
✓ Branch 0 taken 63476780 times.
✓ Branch 1 taken 69544925 times.
133021705 if (!s1->valid) s1 = s0;
6896
2/2
✓ Branch 0 taken 103150925 times.
✓ Branch 1 taken 29870780 times.
133021705 if (!s2->valid) s2 = s0;
6897 133021705 return _walkflag_new(s0, s1, s2, zx, zy, standing_z_state, true);
6898 }
6899
6900 128587954 bool _walkflag(zfix_round x,zfix_round y,int32_t cnt,zfix const& standing_z_state)
6901 {
6902 128587954 int max_x = world_w;
6903 128587954 int max_y = world_h;
6904
2/2
✓ Branch 0 taken 68545217 times.
✓ Branch 1 taken 60042737 times.
128587954 if (!get_qr(qr_LTTPWALK))
6905 {
6906 60042737 max_x -= 7;
6907 60042737 max_y -= 7;
6908 60042737 }
6909
4/4
✓ Branch 0 taken 128317122 times.
✓ Branch 1 taken 270832 times.
✓ Branch 2 taken 83268 times.
✓ Branch 3 taken 128233854 times.
128587954 if (x < 0 || y < 0) return false;
6910
2/2
✓ Branch 0 taken 322356 times.
✓ Branch 1 taken 127911498 times.
128233854 if (x >= max_x) return false;
6911
3/4
✓ Branch 0 taken 539663 times.
✓ Branch 1 taken 127371835 times.
✓ Branch 2 taken 539663 times.
✗ Branch 3 not taken.
127911498 if (x >= max_x - 8 && cnt == 2) return false;
6912
2/2
✓ Branch 0 taken 127362274 times.
✓ Branch 1 taken 549224 times.
127911498 if (y >= max_y) return false;
6913
6914
4/4
✓ Branch 0 taken 29465504 times.
✓ Branch 1 taken 97896770 times.
✓ Branch 2 taken 92237339 times.
✓ Branch 3 taken 5659431 times.
127362274 return _walkflag_new(x, y, standing_z_state) || (cnt != 1 && _walkflag_new(x + 8, y, standing_z_state));
6915 128587954 }
6916
6917 99143870 static bool effectflag(int32_t x, int32_t y, int32_t layer)
6918 {
6919 99143870 mapscr* s0 = get_scr_for_world_xy(x, y);
6920 99143870 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
6921 99143870 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
6922
2/2
✓ Branch 0 taken 51514522 times.
✓ Branch 1 taken 47629348 times.
99143870 if (!s1->valid) s1 = s0;
6923
2/2
✓ Branch 0 taken 17652787 times.
✓ Branch 1 taken 81491083 times.
99143870 if (!s2->valid) s2 = s0;
6924
6925 99143870 int pos = COMBOPOS(x % 256, y % 176);
6926 99143870 const newcombo& c = combobuf[s0->data[pos]];
6927 99143870 const newcombo& c1 = combobuf[s1->data[pos]];
6928 99143870 const newcombo& c2 = combobuf[s2->data[pos]];
6929
4/4
✓ Branch 0 taken 98216592 times.
✓ Branch 1 taken 927278 times.
✓ Branch 2 taken 98215226 times.
✓ Branch 3 taken 1366 times.
198287740 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
6930
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 98215226 times.
✓ Branch 2 taken 926808 times.
✓ Branch 3 taken 1836 times.
99143870 (iswater_type(c2.type))) && DRIEDLAKE);
6931 99143870 int32_t b=1;
6932
2/2
✓ Branch 0 taken 49874789 times.
✓ Branch 1 taken 49269081 times.
99143870 if(x&8) b<<=2;
6933
2/2
✓ Branch 0 taken 41816616 times.
✓ Branch 1 taken 57327254 times.
99143870 if(y&8) b<<=1;
6934
6935 99143870 int32_t cwalkflag = (c.walk>>4);
6936
2/2
✓ Branch 0 taken 76350269 times.
✓ Branch 1 taken 22793601 times.
99143870 if (layer == 0) cwalkflag = (c1.walk>>4);
6937
2/2
✓ Branch 0 taken 76351467 times.
✓ Branch 1 taken 22792403 times.
99143870 if (layer == 1) cwalkflag = (c2.walk>>4);
6938 //if (c.type == cBRIDGE || (iswater_type(c.type) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
6939
4/4
✓ Branch 0 taken 51514522 times.
✓ Branch 1 taken 47629348 times.
✓ Branch 2 taken 22464483 times.
✓ Branch 3 taken 29050039 times.
99143870 if (s1 != s0 && layer < 0)
6940 {
6941
2/2
✓ Branch 0 taken 22451077 times.
✓ Branch 1 taken 13406 times.
22464483 if (c1.type == cBRIDGE) cwalkflag &= (~(c1.walk>>4));
6942 22464483 }
6943
4/4
✓ Branch 0 taken 17652787 times.
✓ Branch 1 taken 81491083 times.
✓ Branch 2 taken 13091910 times.
✓ Branch 3 taken 4560877 times.
99143870 if (s2 != s0 && layer < 1)
6944 {
6945
2/2
✓ Branch 0 taken 13086050 times.
✓ Branch 1 taken 5860 times.
13091910 if (c2.type == cBRIDGE) cwalkflag &= (~(c2.walk>>4));
6946 13091910 }
6947
6948
2/2
✓ Branch 0 taken 98984616 times.
✓ Branch 1 taken 159254 times.
99143870 return (cwalkflag&b) ? !dried : false;
6949 }
6950
6951 99518754 bool _effectflag(int32_t x,int32_t y,int32_t cnt, int32_t layer, bool notLink)
6952 {
6953 DCHECK(cnt == 0 || cnt == 1);
6954 99518754 int max_x = world_w;
6955 99518754 int max_y = world_h;
6956
3/4
✓ Branch 0 taken 45833723 times.
✓ Branch 1 taken 53685031 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45833723 times.
99518754 if (!get_qr(qr_LTTPWALK) && !notLink)
6957 {
6958 45833723 max_x -= 7;
6959 45833723 max_y -= 7;
6960 45833723 }
6961
4/4
✓ Branch 0 taken 99518001 times.
✓ Branch 1 taken 753 times.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 99517797 times.
99518754 if (x < 0 || y < 0) return false;
6962
2/2
✓ Branch 0 taken 818 times.
✓ Branch 1 taken 99516979 times.
99517797 if (x >= max_x) return false;
6963
3/4
✓ Branch 0 taken 521780 times.
✓ Branch 1 taken 98995199 times.
✓ Branch 2 taken 521780 times.
✗ Branch 3 not taken.
99516979 if (x >= max_x - 8 && cnt == 2) return false;
6964
2/2
✓ Branch 0 taken 373109 times.
✓ Branch 1 taken 99143870 times.
99516979 if (y >= max_y) return false;
6965
6966
3/4
✓ Branch 0 taken 98983826 times.
✓ Branch 1 taken 160044 times.
✓ Branch 2 taken 160044 times.
✗ Branch 3 not taken.
99143870 return effectflag(x, y, layer) || (cnt == 2 && effectflag(x + 8, y, layer));
6967 99518754 }
6968
6969 // used by mapdata->isSolid(x,y) in ZScript
6970 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
6971 {
6972 int x = zx.getRound(), y = zy.getRound();
6973 {
6974 int max_x = 256;
6975 int max_y = 176;
6976 if (!get_qr(qr_LTTPWALK))
6977 {
6978 max_x -= 7;
6979 max_y -= 7;
6980 }
6981 if (x < 0 || y < 0) return false;
6982 if (x >= max_x) return false;
6983 if (x >= max_x - 8 && cnt == 2) return false;
6984 if (y >= max_y) return false;
6985 }
6986
6987 const mapscr *s1, *s2;
6988
6989 if ( m->layermap[0] > 0 )
6990 {
6991 s1 = get_canonical_scr(m->layermap[0], m->layerscreen[0]);
6992 }
6993 else s1 = m;
6994
6995 if ( m->layermap[1] > 0 )
6996 {
6997 s2 = get_canonical_scr(m->layermap[1], m->layerscreen[1]);
6998 }
6999 else s2 = m;
7000
7001 zfix unused;
7002 return _walkflag_new(m, s1, s2, x, y, unused, false) || (cnt != 1 && _walkflag_new(m, s1, s2, x + 8, y, unused, false));
7003 }
7004
7005 bool _walkflag_layer(zfix_round x, zfix_round y, int32_t layer, int32_t cnt)
7006 {
7007 DCHECK_LAYER_NEG1_INDEX(layer);
7008 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7009 if (!m->is_valid()) return false;
7010 return _walkflag_layer(x, y, cnt, m);
7011 }
7012
7013 static bool _walkflag_layer_new(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m, int max_x, int max_y)
7014 {
7015 int x = zx.getRound(), y = zy.getRound();
7016
7017 if (!get_qr(qr_LTTPWALK))
7018 {
7019 max_x -= 7;
7020 max_y -= 7;
7021 }
7022 if (x < 0 || y < 0) return false;
7023 if (x >= max_x) return false;
7024 if (x >= max_x - 8 && cnt == 2) return false;
7025 if (y >= max_y) return false;
7026
7027 if(!m) return true;
7028
7029 int pos = COMBOPOS(x%256, y%176);
7030 const newcombo* c = &combobuf[m->data[pos]];
7031 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7032 int32_t b=1;
7033
7034 if(x&8) b<<=2;
7035
7036 if(y&8) b<<=1;
7037
7038 if((c->walk&b) && !dried)
7039 return true;
7040
7041 if(cnt==1) return false;
7042
7043 ++pos;
7044
7045 if(!(x&8))
7046 b<<=2;
7047 else
7048 {
7049 c = &combobuf[m->data[pos]];
7050 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7051 b=1;
7052
7053 if(y&8) b<<=1;
7054 }
7055
7056 return (c->walk&b) ? !dried : false;
7057 }
7058
7059 //Only check the given mapscr*, not its layer 1&2
7060 bool _walkflag_layer(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7061 {
7062 return _walkflag_layer_new(zx, zy, cnt, m, world_w, world_h);
7063 }
7064
7065 bool _walkflag_layer_scrolling(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7066 {
7067 return _walkflag_layer_new(zx, zy, cnt, m, scrolling_region.width, scrolling_region.height);
7068 }
7069
7070 313446 bool _effectflag_layer(int32_t x, int32_t y, int32_t layer, int32_t cnt, bool notLink)
7071 {
7072 DCHECK_LAYER_NEG1_INDEX(layer);
7073 313446 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7074
2/2
✓ Branch 0 taken 1762 times.
✓ Branch 1 taken 311684 times.
313446 if (!m->is_valid()) return false;
7075 311684 return _effectflag_layer(x, y, cnt, m, notLink);
7076 313446 }
7077
7078 377717 bool _effectflag_layer(int32_t x,int32_t y,int32_t cnt, mapscr* m, bool notLink)
7079 {
7080 377717 int max_x = world_w;
7081 377717 int max_y = world_h;
7082
3/4
✓ Branch 0 taken 50002 times.
✓ Branch 1 taken 327715 times.
✓ Branch 2 taken 50002 times.
✗ Branch 3 not taken.
377717 if (!get_qr(qr_LTTPWALK) && !notLink)
7083 {
7084 max_x -= 7;
7085 max_y -= 7;
7086 }
7087
2/4
✓ Branch 0 taken 377717 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 377717 times.
377717 if (x < 0 || y < 0) return false;
7088
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 377717 times.
377717 if (x >= max_x) return false;
7089
3/4
✓ Branch 0 taken 1209 times.
✓ Branch 1 taken 376508 times.
✓ Branch 2 taken 1209 times.
✗ Branch 3 not taken.
377717 if (x >= max_x - 8 && cnt == 2) return false;
7090
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 377717 times.
377717 if (y >= max_y) return false;
7091
7092
1/2
✓ Branch 0 taken 377717 times.
✗ Branch 1 not taken.
377717 if (!m) return true;
7093
7094 377717 int pos = COMBOPOS(x%256, y%176);
7095 377717 const newcombo* c = &combobuf[m->data[pos]];
7096
3/4
✓ Branch 0 taken 377336 times.
✓ Branch 1 taken 381 times.
✓ Branch 2 taken 381 times.
✗ Branch 3 not taken.
378098 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7097 377717 int32_t b=1;
7098
7099
2/2
✓ Branch 0 taken 205340 times.
✓ Branch 1 taken 172377 times.
377717 if(x&8) b<<=2;
7100
7101
2/2
✓ Branch 0 taken 157087 times.
✓ Branch 1 taken 220630 times.
377717 if(y&8) b<<=1;
7102
7103
3/4
✓ Branch 0 taken 308723 times.
✓ Branch 1 taken 68994 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 308723 times.
377717 if(((c->walk>>4)&b) && !dried)
7104 308723 return true;
7105
7106
1/2
✓ Branch 0 taken 68994 times.
✗ Branch 1 not taken.
68994 if(cnt==1) return false;
7107
7108 ++pos;
7109
7110 if(!(x&8))
7111 b<<=2;
7112 else
7113 {
7114 c = &combobuf[m->data[pos]];
7115 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7116 b=1;
7117
7118 if(y&8) b<<=1;
7119 }
7120
7121 return ((c->walk>>4)&b) ? !dried : false;
7122 377717 }
7123
7124 812605 bool water_walkflag(int32_t x, int32_t y, int32_t cnt)
7125 {
7126 812605 int max_x = world_w;
7127 812605 int max_y = world_h;
7128
2/2
✓ Branch 0 taken 117367 times.
✓ Branch 1 taken 695238 times.
812605 if (!get_qr(qr_LTTPWALK))
7129 {
7130 695238 max_x -= 7;
7131 695238 max_y -= 7;
7132 695238 }
7133
2/4
✓ Branch 0 taken 812605 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 812605 times.
812605 if (x < 0 || y < 0) return false;
7134
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if (x >= max_x) return false;
7135
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
812605 if (x >= max_x - 8 && cnt == 2) return false;
7136
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if (y >= max_y) return false;
7137
7138
3/4
✓ Branch 0 taken 16825 times.
✓ Branch 1 taken 795780 times.
✓ Branch 2 taken 795780 times.
✗ Branch 3 not taken.
812605 return water_walkflag(x, y) || (cnt != 1 && water_walkflag(x + 8, y));
7139 812605 }
7140
7141 812605 bool water_walkflag(int32_t x, int32_t y)
7142 {
7143 812605 const newcombo& c = combobuf[MAPCOMBO2(-1, x, y)];
7144 812605 const newcombo& c1 = combobuf[MAPCOMBO2(0, x, y)];
7145 812605 const newcombo& c2 = combobuf[MAPCOMBO2(1, x, y)];
7146
7147 812605 int32_t b=1;
7148
2/2
✓ Branch 0 taken 414677 times.
✓ Branch 1 taken 397928 times.
812605 if(x&8) b<<=2;
7149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if(y&8) b<<=1;
7150
7151
2/2
✓ Branch 0 taken 26377 times.
✓ Branch 1 taken 786228 times.
812605 if(get_qr(qr_NO_SOLID_SWIM))
7152 {
7153
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 26245 times.
26377 if(c.walk&b)
7154 132 return true;
7155
7156
2/2
✓ Branch 0 taken 292 times.
✓ Branch 1 taken 25953 times.
26245 if(c1.walk&b)
7157 292 return true;
7158
7159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25953 times.
25953 if(c2.walk&b)
7160 return true;
7161 25953 }
7162 else
7163 {
7164
4/4
✓ Branch 0 taken 36133 times.
✓ Branch 1 taken 750095 times.
✓ Branch 2 taken 19762 times.
✓ Branch 3 taken 16371 times.
786228 if((c.walk&b) && !iswater_type(c.type))
7165 16371 return true;
7166
7167
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 769840 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
769857 if((c1.walk&b) && !iswater_type(c1.type))
7168 17 return true;
7169
7170
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 769827 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
769840 if((c2.walk&b) && !iswater_type(c2.type))
7171 13 return true;
7172 }
7173
7174 795780 return false;
7175 812605 }
7176
7177 564116 bool hit_walkflag(int32_t x,int32_t y,int32_t cnt)
7178 {
7179
2/2
✓ Branch 0 taken 90999 times.
✓ Branch 1 taken 473117 times.
564116 if(dlevel)
7180
8/8
✓ Branch 0 taken 471712 times.
✓ Branch 1 taken 1405 times.
✓ Branch 2 taken 468517 times.
✓ Branch 3 taken 3195 times.
✓ Branch 4 taken 466857 times.
✓ Branch 5 taken 1660 times.
✓ Branch 6 taken 4199 times.
✓ Branch 7 taken 462658 times.
473117 if(x<32 || y<40 || (x+(cnt-1)*8)>=world_w-32 || y>=world_h-32)
7181 10459 return true;
7182
7183
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 553655 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
553657 if(blockpath && y<((get_qr(qr_LTTPCOLLISION))?80:88))
7184 return true;
7185
7186
8/8
✓ Branch 0 taken 553388 times.
✓ Branch 1 taken 269 times.
✓ Branch 2 taken 553155 times.
✓ Branch 3 taken 233 times.
✓ Branch 4 taken 552946 times.
✓ Branch 5 taken 209 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 552600 times.
553657 if(x<16 || y<16 || (x+(cnt-1)*8)>=world_w-16 || y>=world_h-16)
7187 1057 return true;
7188
7189 // for(int32_t i=0; i<4; i++)
7190
4/4
✓ Branch 0 taken 841 times.
✓ Branch 1 taken 551759 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 805 times.
552600 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7191 36 return true;
7192
7193
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 552564 times.
552564 if (collide_object(x, y,cnt*8, 1))
7194 return true;
7195
7196 552564 return _walkflag(x,y,cnt);
7197 564116 }
7198
7199 12110 bool solpush_walkflag(int32_t x, int32_t y, int32_t cnt, solid_object const* ign)
7200 {
7201 // 16 pixel buffer to account for slopes that are on bordering screens.
7202
4/8
✓ Branch 0 taken 12110 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12110 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12110 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12110 times.
12110 if(x<0 || y<0 || x>=world_w+16 || y>=world_h+16)
7203 return true;
7204
7205 // for(int32_t i=0; i<4; i++)
7206
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12110 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12110 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7207 return true;
7208
7209
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12110 times.
12110 if (collide_object(x, y,cnt*8, 1, ign))
7210 return true;
7211
7212 12110 return _walkflag(x,y,cnt);
7213 12110 }
7214
7215 37837 void map_bkgsfx(bool on)
7216 {
7217
2/2
✓ Branch 0 taken 37816 times.
✓ Branch 1 taken 21 times.
37837 if(on)
7218 {
7219 37816 cont_sfx(hero_scr->oceansfx);
7220
7221
4/4
✓ Branch 0 taken 369 times.
✓ Branch 1 taken 37447 times.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 54 times.
37816 if(hero_scr->bosssfx && !(game->lvlitems[dlevel]&liBOSS))
7222 315 cont_sfx(hero_scr->bosssfx);
7223 37816 }
7224 else
7225 {
7226 21 adjust_sfx(hero_scr->oceansfx,128,false);
7227 21 adjust_sfx(hero_scr->bosssfx,128,false);
7228
7229
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 21 times.
135 for(int32_t i=0; i<guys.Count(); i++)
7230 {
7231
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 84 times.
114 if(((enemy*)guys.spr(i))->bgsfx)
7232 84 stop_sfx(((enemy*)guys.spr(i))->bgsfx);
7233 114 }
7234 }
7235 37837 }
7236
7237 239 void toggle_switches(dword flags, bool entry)
7238 {
7239
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 239 times.
239 if(!flags) return; //No flags to toggle
7240
7241 478 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7242 239 toggle_switches(flags, entry, create_screen_handles(scr));
7243 239 });
7244 239 }
7245 54044 void toggle_switches(dword flags, bool entry, const screen_handles_t& screen_handles)
7246 {
7247
2/2
✓ Branch 0 taken 737 times.
✓ Branch 1 taken 53307 times.
54044 if(!flags) return; //No flags to toggle
7248
7249 737 mapscr* m = screen_handles[0].base_scr;
7250 737 int screen = m->screen;
7251 737 bool is_active_screen = is_in_current_region(m);
7252
7253 305041 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
7254 304304 byte togglegrid[176] = {0};
7255 304304 mapscr* scr = rpos_handle.scr;
7256 304304 int lyr = rpos_handle.layer;
7257 304304 int pos = rpos_handle.pos;
7258 304304 newcombo const& cmb = combobuf[scr->data[pos]];
7259
2/2
✓ Branch 0 taken 39424 times.
✓ Branch 1 taken 264880 times.
304304 if(is_active_screen)
7260
1/2
✓ Branch 0 taken 264880 times.
✗ Branch 1 not taken.
367773 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7261
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 102893 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
102893 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7262 }, ctrigSWITCHSTATE);
7263
3/4
✓ Branch 0 taken 303641 times.
✓ Branch 1 taken 663 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2760 times.
304304 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32
7264
2/2
✓ Branch 0 taken 2760 times.
✓ Branch 1 taken 301544 times.
304304 && !(cmb.usrflags & cflag11)) //global state
7265 {
7266
2/2
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 2314 times.
2760 if(flags&(1<<cmb.attribytes[0]))
7267 {
7268 2314 set<int32_t> oldData;
7269 //Increment the combo/cset by the attributes
7270 2314 int32_t cmbofs = (cmb.attributes[0]/10000L);
7271 2314 int32_t csofs = (cmb.attributes[1]/10000L);
7272
1/2
✓ Branch 0 taken 2314 times.
✗ Branch 1 not taken.
2314 oldData.insert(scr->data[pos]);
7273
1/2
✓ Branch 0 taken 2314 times.
✗ Branch 1 not taken.
2314 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7274 2314 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7275
4/4
✓ Branch 0 taken 1435 times.
✓ Branch 1 taken 879 times.
✓ Branch 2 taken 1197 times.
✓ Branch 3 taken 238 times.
2314 if(entry && (cmb.usrflags&cflag8))
7276 {
7277 238 newcombo const* tmp = &combobuf[scr->data[pos]];
7278
2/4
✓ Branch 0 taken 238 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 238 times.
✗ Branch 3 not taken.
238 while(tmp->can_cycle())
7279 {
7280 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7281 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7282 if(oldData.find(cid) != oldData.end())
7283 break;
7284
7285 scr->data[pos] = cid;
7286 if(!(tmp->animflags & AF_CYCLENOCSET))
7287 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7288 oldData.insert(cid);
7289 tmp = &combobuf[cid];
7290 }
7291 238 }
7292 2314 int32_t cmbid = scr->data[pos];
7293
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 2273 times.
2314 if(combobuf[cmbid].animflags & AF_CYCLE)
7294 {
7295 41 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7296 41 combobuf[cmbid].cur_frame=0;
7297 41 combobuf[cmbid].aclk = 0;
7298
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 combo_caches::drawing.refresh(cmbid);
7299 41 }
7300 2314 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7301
2/2
✓ Branch 0 taken 511 times.
✓ Branch 1 taken 1803 times.
2314 if(cmb.type == cCSWITCH) return; //Switches don't toggle other layers
7302
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2147 times.
2147 for(int32_t lyr2 = 0; lyr2 < 7; ++lyr2) //Toggle same pos on other layers, if flag set
7303 {
7304
2/2
✓ Branch 0 taken 1671 times.
✓ Branch 1 taken 476 times.
2147 if(lyr==lyr2) return;
7305
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 344 times.
476 if(!(cmb.usrflags&(1<<lyr2))) return;
7306
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(togglegrid[pos]&(1<<lyr2)) return;
7307
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
344 mapscr* scr_2 = (lyr2 ? get_scr_layer(screen, lyr2) : m);
7308
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(!scr_2->data[pos]) //Don't increment empty space
7309 return;
7310 344 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7311
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
344 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK) && !(cmb.usrflags & cflag11)
7312 && cmb_2.attribytes[0] < 32 && (flags&(1<<cmb_2.attribytes[0])))
7313 return; //This is a switch/block that will be hit later in the loop!
7314 344 set<int32_t> oldData2;
7315 //Increment the combo/cset by the original cmb's attributes
7316
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 oldData2.insert(scr_2->data[pos]);
7317
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7318 344 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7319
3/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
344 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7320 {
7321 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7322 while(tmp->can_cycle())
7323 {
7324 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7325 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7326 if(oldData2.find(cid) != oldData2.end())
7327 break;
7328
7329 scr_2->data[pos] = cid;
7330 if(!(tmp->animflags & AF_CYCLENOCSET))
7331 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7332 oldData2.insert(cid);
7333 tmp = &combobuf[cid];
7334 }
7335 }
7336 344 int32_t cmbid2 = scr_2->data[pos];
7337
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(combobuf[cmbid2].animflags & AF_CYCLE)
7338 {
7339 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7340 combobuf[cmbid2].cur_frame=0;
7341 combobuf[cmbid2].aclk = 0;
7342 combo_caches::drawing.refresh(cmbid2);
7343 }
7344 344 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7345 344 }
7346
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 2314 times.
✗ Branch 2 not taken.
2314 }
7347 446 }
7348 304304 });
7349
7350
3/4
✓ Branch 0 taken 519 times.
✓ Branch 1 taken 218 times.
✓ Branch 2 taken 519 times.
✗ Branch 3 not taken.
737 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7351 {
7352 newcombo const& cmb = combobuf[mblock2.bcombo];
7353 if(!(cmb.usrflags & cflag11) && (cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32)
7354 {
7355 if(flags&(1<<cmb.attribytes[0]))
7356 {
7357 //Increment the combo/cset by the attributes
7358 int32_t cmbofs = (cmb.attributes[0]/10000L);
7359 int32_t csofs = (cmb.attributes[1]/10000L);
7360 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7361 mblock2.cs = (mblock2.cs + csofs) & 15;
7362 int32_t cmbid = mblock2.bcombo;
7363 if(combobuf[cmbid].animflags & AF_CYCLE)
7364 {
7365 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7366 combobuf[cmbid].cur_frame=0;
7367 combobuf[cmbid].aclk = 0;
7368 combo_caches::drawing.refresh(cmbid);
7369 }
7370 }
7371 }
7372 }
7373
7374
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 513 times.
737 if (is_active_screen)
7375 {
7376 513 int screen_index_offset = get_region_screen_offset(m->screen);
7377 513 word c = m->numFFC();
7378
2/2
✓ Branch 0 taken 334 times.
✓ Branch 1 taken 513 times.
847 for (int q = 0; q < c; ++q)
7379 {
7380 334 auto ffc_handle = *m->getFFCHandle(q, screen_index_offset);
7381
1/2
✓ Branch 0 taken 334 times.
✗ Branch 1 not taken.
363 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7382
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
29 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7383 }, ctrigSWITCHSTATE);
7384 334 }
7385 513 }
7386 54044 }
7387
7388 1 void toggle_gswitches(int32_t state, bool entry)
7389 {
7390 2 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7391 1 toggle_gswitches(state, entry, create_screen_handles(scr));
7392 1 });
7393 1 }
7394 1 void toggle_gswitches(int32_t state, bool entry, const screen_handles_t& screen_handles)
7395 {
7396 1 bool states[256] = {false};
7397 1 states[state] = true;
7398 1 toggle_gswitches(states, entry, screen_handles);
7399 1 }
7400 15216334 void toggle_gswitches(bool* states, bool entry, const screen_handles_t& screen_handles)
7401 {
7402
1/2
✓ Branch 0 taken 15216334 times.
✗ Branch 1 not taken.
15216334 if(!states) return;
7403
7404 15216334 auto& combo_cache = combo_caches::gswitch;
7405 15216334 mapscr* base_scr = screen_handles[0].base_scr;
7406 15216334 int screen = base_scr->screen;
7407 15216334 bool is_active_screen = is_in_current_region(base_scr);
7408 15216334 byte togglegrid[176] = {0};
7409
2/2
✓ Branch 0 taken 15216334 times.
✓ Branch 1 taken 106514338 times.
121730672 for(int32_t lyr = 0; lyr <= 6; ++lyr)
7410 {
7411 106514338 mapscr* scr = screen_handles[lyr].scr;
7412
2/2
✓ Branch 0 taken 32314143 times.
✓ Branch 1 taken 74200195 times.
106514338 if (!scr)
7413 74200195 continue;
7414
7415
2/2
✓ Branch 0 taken 32314143 times.
✓ Branch 1 taken 5687289168 times.
5719603311 for(int32_t pos = 0; pos < 176; ++pos)
7416 {
7417 5687289168 int cid = scr->data[pos];
7418 5687289168 auto& mini_cmb = combo_cache.minis[cid];
7419
7420
2/2
✓ Branch 0 taken 93475360 times.
✓ Branch 1 taken 5593813808 times.
5687289168 if (is_active_screen)
7421 {
7422
2/2
✓ Branch 0 taken 5593811926 times.
✓ Branch 1 taken 1882 times.
5593813808 if (mini_cmb.trigger_global_state)
7423 {
7424 1882 auto rpos_handle = get_rpos_handle_for_screen(screen, lyr, pos);
7425
1/2
✓ Branch 0 taken 1882 times.
✗ Branch 1 not taken.
3764 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7426
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1882 times.
1882 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7427 }, ctrigSWITCHSTATE);
7428 1882 }
7429 5593813808 }
7430
7431
2/2
✓ Branch 0 taken 40395 times.
✓ Branch 1 taken 5687248773 times.
5687289168 if (!mini_cmb.has_global_state)
7432 5687248773 continue;
7433
7434 40395 newcombo const& cmb = combobuf[cid];
7435
2/4
✓ Branch 0 taken 40395 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40395 times.
40395 if(cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK)
7436 {
7437 if(states[cmb.attribytes[0]])
7438 {
7439 set<int32_t> oldData;
7440 //Increment the combo/cset by the attributes
7441 int32_t cmbofs = (cmb.attributes[0]/10000L);
7442 int32_t csofs = (cmb.attributes[1]/10000L);
7443 oldData.insert(scr->data[pos]);
7444 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7445 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7446 if(entry && (cmb.usrflags&cflag8))
7447 {
7448 newcombo const* tmp = &combobuf[scr->data[pos]];
7449 while(tmp->can_cycle())
7450 {
7451 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7452 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7453 if(oldData.find(cid) != oldData.end())
7454 break;
7455 scr->data[pos] = cid;
7456 if(!(tmp->animflags & AF_CYCLENOCSET))
7457 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7458 oldData.insert(cid);
7459 tmp = &combobuf[cid];
7460 }
7461 }
7462 int32_t cmbid = scr->data[pos];
7463 if(combobuf[cmbid].animflags & AF_CYCLE)
7464 {
7465 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7466 combobuf[cmbid].cur_frame=0;
7467 combobuf[cmbid].aclk = 0;
7468 combo_caches::drawing.refresh(cmbid);
7469 }
7470 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7471 if(cmb.type == cCSWITCH) continue; //Switches don't toggle other layers
7472 for(int32_t lyr2 = 0; lyr2 <= 6; ++lyr2) //Toggle same pos on other layers, if flag set
7473 {
7474 if(lyr==lyr2) continue;
7475 if(!(cmb.usrflags&(1<<lyr2))) continue;
7476 if(togglegrid[pos]&(1<<lyr2)) continue;
7477 mapscr* scr_2 = lyr2 == 0 ? base_scr : get_scr_layer_valid(screen, lyr2);
7478 if(!scr_2 || !scr_2->data[pos]) //Don't increment empty space
7479 continue;
7480 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7481 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK)
7482 && (cmb_2.usrflags & cflag11) && (states[cmb_2.attribytes[0]]))
7483 continue; //This is a switch/block that will be hit later in the loop!
7484 set<int32_t> oldData2;
7485 //Increment the combo/cset by the original cmb's attributes
7486 oldData2.insert(scr_2->data[pos]);
7487 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7488 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7489 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7490 {
7491 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7492 while(tmp->can_cycle())
7493 {
7494 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7495 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7496 if(oldData2.find(cid) != oldData2.end())
7497 break;
7498 scr_2->data[pos] = cid;
7499 if(!(tmp->animflags & AF_CYCLENOCSET))
7500 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7501 oldData2.insert(cid);
7502 tmp = &combobuf[cid];
7503 }
7504 }
7505 int32_t cmbid2 = scr_2->data[pos];
7506 if(combobuf[cmbid2].animflags & AF_CYCLE)
7507 {
7508 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7509 combobuf[cmbid2].cur_frame=0;
7510 combobuf[cmbid2].aclk = 0;
7511 combo_caches::drawing.refresh(cmbid2);
7512 }
7513 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7514 }
7515 }
7516 }
7517 40395 }
7518 32314143 }
7519
7520
4/4
✓ Branch 0 taken 547048 times.
✓ Branch 1 taken 14669286 times.
✓ Branch 2 taken 542304 times.
✓ Branch 3 taken 4744 times.
15216334 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7521 {
7522 4744 newcombo const& cmb = combobuf[mblock2.bcombo];
7523
2/4
✓ Branch 0 taken 4744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4744 times.
✗ Branch 3 not taken.
4744 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && (cmb.usrflags & cflag11))
7524 {
7525 if(states[cmb.attribytes[0]])
7526 {
7527 //Increment the combo/cset by the attributes
7528 int32_t cmbofs = (cmb.attributes[0]/10000L);
7529 int32_t csofs = (cmb.attributes[1]/10000L);
7530 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7531 mblock2.cs = (mblock2.cs + csofs) & 15;
7532 int32_t cmbid = mblock2.bcombo;
7533 if(combobuf[cmbid].animflags & AF_CYCLE)
7534 {
7535 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7536 combobuf[cmbid].cur_frame=0;
7537 combobuf[cmbid].aclk = 0;
7538 combo_caches::drawing.refresh(cmbid);
7539 }
7540 }
7541 }
7542 4744 }
7543
7544
2/2
✓ Branch 0 taken 413479 times.
✓ Branch 1 taken 14802855 times.
15216334 if(is_active_screen)
7545 {
7546 14802855 int screen_index_offset = get_region_screen_offset(screen);
7547 14802855 word c = base_scr->numFFC();
7548
2/2
✓ Branch 0 taken 441793087 times.
✓ Branch 1 taken 14802855 times.
456595942 for (int q = 0; q < c; ++q)
7549 {
7550 441793087 auto ffc_handle = *base_scr->getFFCHandle(q, screen_index_offset);
7551
1/2
✓ Branch 0 taken 441793087 times.
✗ Branch 1 not taken.
442021875 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7552
1/2
✓ Branch 0 taken 228788 times.
✗ Branch 1 not taken.
228788 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7553 }, ctrigSWITCHSTATE);
7554 441793087 }
7555 14802855 }
7556 15216334 }
7557 53805 void toggle_gswitches_load(const screen_handles_t& screen_handles)
7558 {
7559 bool states[256];
7560
2/2
✓ Branch 0 taken 13774080 times.
✓ Branch 1 taken 53805 times.
13827885 for(auto q = 0; q < 256; ++q)
7561 {
7562 13774080 states[q] = game->gswitch_timers[q] != 0;
7563 13774080 }
7564 53805 toggle_gswitches(states, true, screen_handles);
7565 53805 }
7566 14773160 void run_gswitch_timers()
7567 {
7568 14773160 bool states[256] = {false};
7569 14773160 auto& m = game->gswitch_timers.mut_inner();
7570
2/2
✓ Branch 0 taken 3777886720 times.
✓ Branch 1 taken 14773160 times.
3792659880 for(auto it = m.begin(); it != m.end();)
7571 {
7572
2/2
✓ Branch 0 taken 3777886120 times.
✓ Branch 1 taken 600 times.
3777886720 if(it->second > 0)
7573
2/2
✓ Branch 0 taken 599 times.
✓ Branch 1 taken 1 times.
600 if(!--it->second)
7574 {
7575 1 states[it->first] = true;
7576 1 it = m.erase(it);
7577 1 continue;
7578 }
7579 3777886719 ++it;
7580 }
7581 29935688 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7582 15162528 toggle_gswitches(states, false, create_screen_handles(scr));
7583 15162528 });
7584 14773160 }
7585 1116 void onload_gswitch_timers() //Reset all timers that were counting down, no trigger necessary
7586 {
7587
2/2
✓ Branch 0 taken 285696 times.
✓ Branch 1 taken 1116 times.
286812 for(auto q = 0; q < 256; ++q)
7588 {
7589
1/2
✓ Branch 0 taken 285696 times.
✗ Branch 1 not taken.
285696 if(game->gswitch_timers[q] > 0)
7590 game->gswitch_timers[q] = 0;
7591 285696 }
7592 1116 }
7593
7594 /**** View Map ****/
7595
7596 int32_t mapres = 0;
7597 int32_t view_map_show_mode = 3;
7598
7599 124544 bool displayOnMap(int32_t x, int32_t y)
7600 {
7601 124544 int32_t s = (y<<4) + x;
7602 124544 int mi = mapind(cur_map, s);
7603
2/2
✓ Branch 0 taken 67891 times.
✓ Branch 1 taken 56653 times.
124544 if (!(game->maps[mi]&mVISITED))
7604 67891 return false;
7605
7606 // Don't display if not part of DMap
7607
4/4
✓ Branch 0 taken 15628 times.
✓ Branch 1 taken 41025 times.
✓ Branch 2 taken 4655 times.
✓ Branch 3 taken 4311 times.
65619 if(((DMaps[cur_dmap].flags&dmfDMAPMAP) &&
7608
1/2
✓ Branch 0 taken 15628 times.
✗ Branch 1 not taken.
15628 (DMaps[cur_dmap].type != dmOVERW) &&
7609
2/2
✓ Branch 0 taken 12495 times.
✓ Branch 1 taken 3133 times.
15628 !(x >= DMaps[cur_dmap].xoff &&
7610
2/2
✓ Branch 0 taken 8966 times.
✓ Branch 1 taken 3529 times.
12495 x < DMaps[cur_dmap].xoff+8 &&
7611 8966 DMaps[cur_dmap].grid[y]&(128>>(x-DMaps[cur_dmap].xoff)))))
7612 10973 return false;
7613 else
7614 45680 return true;
7615 124544 }
7616
7617 973 void ViewMap()
7618 {
7619 973 ViewingMap = true;
7620
7621 973 BITMAP* mappic = NULL;
7622 static double scales[17] =
7623 {
7624 0.03125, 0.04419, 0.0625, 0.08839, 0.125, 0.177, 0.25, 0.3535,
7625 0.50, 0.707, 1.0, 1.414, 2.0, 2.828, 4.0, 5.657, 8.0
7626 };
7627
7628 973 int32_t px = ((8-(cur_screen&15)) << 9) - 256;
7629 973 int32_t py = ((4-(cur_screen>>4)) * 352) - 176;
7630 973 int32_t lx = ((cur_screen&15)<<8) + HeroX()+8;
7631 973 int32_t ly = ((cur_screen>>4)*176) + HeroY()+8;
7632 973 int32_t sc = 6;
7633
7634 973 bool done=false, redraw=true;
7635
7636 973 mappic = create_bitmap_ex(8,(256*16)>>mapres,(176*8)>>mapres);
7637
7638
1/2
✓ Branch 0 taken 973 times.
✗ Branch 1 not taken.
973 if(!mappic)
7639 {
7640 enter_sys_pal();
7641 jwin_alert("View Map","Not enough memory.",NULL,NULL,"OK",NULL,13,27,get_zc_font(font_lfont));
7642 exit_sys_pal();
7643 return;
7644 }
7645
7646 973 clear_to_color(mappic, WHITE);
7647
7648 973 auto prev_viewport = viewport;
7649 973 viewport.x = 0;
7650 973 viewport.y = 0;
7651
7652 // draw the map
7653 973 BITMAP* screen_bmp = create_bitmap_ex(8, 256, 176);
7654 973 combotile_add_x = 256;
7655 973 combotile_add_y = 0;
7656
2/2
✓ Branch 0 taken 7784 times.
✓ Branch 1 taken 973 times.
8757 for(int32_t y=0; y<8; y++)
7657 {
7658
2/2
✓ Branch 0 taken 124544 times.
✓ Branch 1 taken 7784 times.
132328 for(int32_t x=0; x<16; x++)
7659 {
7660
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 78864 times.
124544 if (!displayOnMap(x, y))
7661 78864 continue;
7662
7663 45680 int screen = map_scr_xy_to_index(x, y);
7664 45680 auto scrs = loadscr2(screen);
7665 45680 mapscr* scr = &scrs[0];
7666
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if (!scr->is_valid())
7667 continue;
7668
7669 screen_handles_t screen_handles;
7670
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 319760 times.
365440 for (int i = 0; i <= 6; i++)
7671
3/4
✓ Branch 0 taken 319760 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103790 times.
✓ Branch 3 taken 215970 times.
319760 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
7672
7673 45680 int xx = 0;
7674 45680 int yy = -playing_field_offset;
7675
7676
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 45660 times.
45680 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7677 {
7678
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7679
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7680 20 }
7681
7682
2/2
✓ Branch 0 taken 175 times.
✓ Branch 1 taken 45505 times.
45680 if(XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
7683 {
7684
1/2
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
175 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7685
1/2
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
175 do_ffc_layer(screen_bmp, -3, screen_handles[0], xx, yy);
7686 175 }
7687
7688
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if(lenscheck(scr,0)) putscr(scr, screen_bmp, 0, 0);
7689
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 0, screen_handles[0], xx, yy);
7690
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[1], xx, yy);
7691
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 1, screen_handles[0], xx, yy);
7692
7693
2/2
✓ Branch 0 taken 45660 times.
✓ Branch 1 taken 20 times.
45680 if(!XOR((scr->flags7&fLAYER2BG), DMaps[cur_dmap].flags&dmfLAYER2BG))
7694 {
7695
1/2
✓ Branch 0 taken 45660 times.
✗ Branch 1 not taken.
45660 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7696
1/2
✓ Branch 0 taken 45660 times.
✗ Branch 1 not taken.
45660 do_ffc_layer(screen_bmp, 2, screen_handles[0], xx, yy);
7697 45660 }
7698
7699
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 putscrdoors(scr, screen_bmp, xx, yy);
7700
2/2
✓ Branch 0 taken 41678 times.
✓ Branch 1 taken 4002 times.
45680 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
7701 {
7702
1/2
✓ Branch 0 taken 41678 times.
✗ Branch 1 not taken.
41678 do_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7703
2/2
✓ Branch 0 taken 1782 times.
✓ Branch 1 taken 39896 times.
41678 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
7704 {
7705
1/2
✓ Branch 0 taken 1782 times.
✗ Branch 1 not taken.
1782 do_layer(screen_bmp,-2, screen_handles[1], xx, yy);
7706
1/2
✓ Branch 0 taken 1782 times.
✗ Branch 1 not taken.
1782 do_layer(screen_bmp,-2, screen_handles[2], xx, yy);
7707 1782 }
7708 41678 }
7709
7710
2/2
✓ Branch 0 taken 45505 times.
✓ Branch 1 taken 175 times.
45680 if(!XOR((scr->flags7&fLAYER3BG), DMaps[cur_dmap].flags&dmfLAYER3BG))
7711 {
7712
1/2
✓ Branch 0 taken 45505 times.
✗ Branch 1 not taken.
45505 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7713
1/2
✓ Branch 0 taken 45505 times.
✗ Branch 1 not taken.
45505 do_ffc_layer(screen_bmp, 3, screen_handles[0], xx, yy);
7714 45505 }
7715
7716
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[4], xx, yy);
7717
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 4, screen_handles[0], xx, yy);
7718
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7719
2/2
✓ Branch 0 taken 5784 times.
✓ Branch 1 taken 39896 times.
45680 if(get_qr(qr_OVERHEAD_COMBOS_L1_L2))
7720 {
7721
1/2
✓ Branch 0 taken 5784 times.
✗ Branch 1 not taken.
5784 do_layer(screen_bmp,-1, screen_handles[1], xx, yy);
7722
1/2
✓ Branch 0 taken 5784 times.
✗ Branch 1 not taken.
5784 do_layer(screen_bmp,-1, screen_handles[2], xx, yy);
7723 5784 }
7724
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[5], xx, yy);
7725
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 5, screen_handles[0], xx, yy);
7726
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45680 times.
45680 if(replay_version_check(40))
7727 do_ffc_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7728
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[6], xx, yy);
7729
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 6, screen_handles[0], xx, yy);
7730
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 7, screen_handles[0], xx, yy);
7731
7732
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 stretch_blit(screen_bmp, mappic, 0, 0, 256, 176, x<<(8-mapres), (y*176)>>mapres, 256>>mapres, 176>>mapres);
7733
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
45680 }
7734 7784 }
7735
7736 973 viewport = prev_viewport;
7737 973 combotile_add_x = 0;
7738 973 combotile_add_y = 0;
7739
7740 973 destroy_bitmap(screen_bmp);
7741 973 clear_keybuf();
7742 973 pause_all_sfx();
7743
7744 // view it
7745 973 int32_t delay = 0;
7746
7747 973 do
7748 {
7749
2/2
✓ Branch 0 taken 178717 times.
✓ Branch 1 taken 29891 times.
208608 if (replay_version_check(0, 11))
7750 29891 load_control_state();
7751
7752 208608 int32_t step = int32_t(16.0/scales[sc]);
7753 208608 step = (step>>1) + (step&1);
7754 208608 bool r = cRbtn();
7755
7756
1/2
✓ Branch 0 taken 208608 times.
✗ Branch 1 not taken.
208608 if(cLbtn())
7757 {
7758 step <<= 2;
7759 delay = 0;
7760 }
7761
7762
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 208608 times.
208608 if(r)
7763 {
7764 if(rUp())
7765 {
7766 py+=step;
7767 redraw=true;
7768 }
7769
7770 if(rDown())
7771 {
7772 py-=step;
7773 redraw=true;
7774 }
7775
7776 if(rLeft())
7777 {
7778 px+=step;
7779 redraw=true;
7780 }
7781
7782 if(rRight())
7783 {
7784 px-=step;
7785 redraw=true;
7786 }
7787 }
7788 else
7789 {
7790
2/2
✓ Branch 0 taken 193729 times.
✓ Branch 1 taken 14879 times.
208608 if(Up())
7791 {
7792 14879 py+=step;
7793 14879 redraw=true;
7794 14879 }
7795
7796
2/2
✓ Branch 0 taken 193574 times.
✓ Branch 1 taken 15034 times.
208608 if(Down())
7797 {
7798 15034 py-=step;
7799 15034 redraw=true;
7800 15034 }
7801
7802
2/2
✓ Branch 0 taken 182159 times.
✓ Branch 1 taken 26449 times.
208608 if(Left())
7803 {
7804 26449 px+=step;
7805 26449 redraw=true;
7806 26449 }
7807
7808
2/2
✓ Branch 0 taken 182774 times.
✓ Branch 1 taken 25834 times.
208608 if(Right())
7809 {
7810 25834 px-=step;
7811 25834 redraw=true;
7812 25834 }
7813 }
7814
7815
2/2
✓ Branch 0 taken 187444 times.
✓ Branch 1 taken 21164 times.
208608 if(delay)
7816 21164 --delay;
7817 else
7818 {
7819 187444 bool a = cAbtn();
7820 187444 bool b = cBbtn();
7821
7822
3/4
✓ Branch 0 taken 1721 times.
✓ Branch 1 taken 185723 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1721 times.
187444 if(a && !b)
7823 {
7824
1/2
✓ Branch 0 taken 1721 times.
✗ Branch 1 not taken.
1721 sc=zc_min(sc+1,16);
7825 1721 delay=8;
7826 1721 redraw=true;
7827 1721 }
7828
7829
3/4
✓ Branch 0 taken 927 times.
✓ Branch 1 taken 186517 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 927 times.
187444 if(b && !a)
7830 {
7831
2/2
✓ Branch 0 taken 926 times.
✓ Branch 1 taken 1 times.
927 sc=zc_max(sc-1,0);
7832 927 delay=8;
7833 927 redraw=true;
7834 927 }
7835 }
7836
7837
2/2
✓ Branch 0 taken 208597 times.
✓ Branch 1 taken 11 times.
208608 if(rPbtn())
7838 11 --view_map_show_mode;
7839
7840 208608 px = vbound(px,-4096,4096);
7841 208608 py = vbound(py,-1408,1408);
7842
7843 208608 double scale = scales[sc];
7844
7845
2/2
✓ Branch 0 taken 72838 times.
✓ Branch 1 taken 135770 times.
208608 if(!redraw)
7846 {
7847 135770 blit(scrollbuf_old,framebuf,256,0,0,0,256,232);
7848 135770 }
7849 else
7850 {
7851 72838 clear_to_color(framebuf,BLACK);
7852 145676 stretch_blit(mappic,framebuf,0,0,mappic->w,mappic->h,
7853 72838 int32_t(256+(int64_t(px)-mappic->w)*scale)/2,int32_t(224+(int64_t(py)-mappic->h)*scale)/2,
7854 72838 int32_t(mappic->w*scale),int32_t(mappic->h*scale));
7855
7856 72838 blit(framebuf,scrollbuf_old,0,0,256,0,256,232);
7857 72838 redraw=false;
7858 }
7859
7860 208608 int32_t x = int32_t(256+(px-((2048-int64_t(lx))*2))*scale)/2;
7861 208608 int32_t y = int32_t(224+(py-((704-int64_t(ly))*2))*scale)/2;
7862
7863
2/2
✓ Branch 0 taken 7466 times.
✓ Branch 1 taken 201142 times.
208608 if(view_map_show_mode&1)
7864 {
7865 201142 line(framebuf,x-7,y-7,x+7,y+7,(frame&3)+252);
7866 201142 line(framebuf,x+7,y-7,x-7,y+7,(frame&3)+252);
7867 201142 }
7868
7869
3/4
✓ Branch 0 taken 5600 times.
✓ Branch 1 taken 203008 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5600 times.
208608 if(view_map_show_mode&2 || r)
7870 203008 textprintf_ex(framebuf,font,224,216,WHITE,BLACK,"%1.2f",scale);
7871
7872
1/2
✓ Branch 0 taken 208608 times.
✗ Branch 1 not taken.
208608 if(r)
7873 {
7874 textprintf_ex(framebuf,font,0,208,WHITE,BLACK,"m: %d %d",px,py);
7875 textprintf_ex(framebuf,font,0,216,WHITE,BLACK,"x: %d %d",x,y);
7876 }
7877
7878 208608 advanceframe(false, false);
7879
2/2
✓ Branch 0 taken 29891 times.
✓ Branch 1 taken 178717 times.
208608 if (replay_version_check(11))
7880 178717 load_control_state();
7881
7882
2/2
✓ Branch 0 taken 207636 times.
✓ Branch 1 taken 972 times.
208608 if(getInput(btnS, true, false, true)) //rSbtn
7883 972 done = true;
7884
7885
2/2
✓ Branch 0 taken 973 times.
✓ Branch 1 taken 207635 times.
417216 }
7886
2/2
✓ Branch 0 taken 972 times.
✓ Branch 1 taken 207636 times.
208608 while(!done && !Quit);
7887
7888 973 ViewingMap = false;
7889 973 destroy_bitmap(mappic);
7890 973 resume_all_sfx();
7891 973 }
7892
7893 1075 int32_t onViewMap()
7894 {
7895
4/6
✓ Branch 0 taken 1075 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1075 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 102 times.
✓ Branch 5 taken 973 times.
1075 if(Playing && cur_screen<128 && DMaps[cur_dmap].flags&dmfVIEWMAP)
7896 {
7897 973 clear_to_color(framebuf,BLACK);
7898 973 textout_centre_ex(framebuf,font,"Drawing map...",128,108,WHITE,BLACK);
7899 973 advanceframe(true);
7900 973 ViewMap();
7901 973 }
7902
7903 1075 return D_O_K;
7904 }
7905
7906 35757403 bool isGrassType(int32_t type)
7907 {
7908
2/2
✓ Branch 0 taken 35080991 times.
✓ Branch 1 taken 676412 times.
35757403 switch(type)
7909 {
7910 case cTALLGRASS:
7911 case cTALLGRASSNEXT:
7912 case cTALLGRASSTOUCHY:
7913 676412 return true;
7914 }
7915
7916 35080991 return false;
7917 35757403 }
7918
7919 20914 bool isFlowersType(int32_t type)
7920 {
7921
2/2
✓ Branch 0 taken 16574 times.
✓ Branch 1 taken 4340 times.
20914 switch(type)
7922 {
7923 case cFLOWERS:
7924 case cFLOWERSTOUCHY:
7925 4340 return true;
7926 }
7927
7928 16574 return false;
7929 20914 }
7930
7931 bool isGenericType(int32_t type)
7932 {
7933 switch(type)
7934 {
7935 case cTRIGGERGENERIC:
7936 return true;
7937 }
7938
7939 return false;
7940 }
7941
7942 26056 bool isBushType(int32_t type)
7943 {
7944
2/2
✓ Branch 0 taken 20914 times.
✓ Branch 1 taken 5142 times.
26056 switch(type)
7945 {
7946 case cBUSH:
7947 case cBUSHNEXT:
7948 case cBUSHTOUCHY:
7949 case cBUSHNEXTTOUCHY:
7950
7951 5142 return true;
7952 }
7953
7954 20914 return false;
7955 26056 }
7956
7957 bool isSlashType(int32_t type)
7958 {
7959 switch(type)
7960 {
7961 case cSLASH:
7962 case cSLASHITEM:
7963 case cSLASHTOUCHY:
7964 case cSLASHITEMTOUCHY:
7965 case cSLASHNEXT:
7966 case cSLASHNEXTITEM:
7967 case cSLASHNEXTTOUCHY:
7968 case cSLASHNEXTITEMTOUCHY:
7969 return true;
7970 }
7971
7972 return false;
7973 }
7974
7975 15695 bool isCuttableNextType(int32_t type)
7976 {
7977
2/2
✓ Branch 0 taken 9788 times.
✓ Branch 1 taken 5907 times.
15695 switch(type)
7978 {
7979 case cSLASHNEXT:
7980 case cSLASHNEXTITEM:
7981 case cTALLGRASSNEXT:
7982 case cBUSHNEXT:
7983 case cSLASHNEXTTOUCHY:
7984 case cSLASHNEXTITEMTOUCHY:
7985 case cBUSHNEXTTOUCHY:
7986 5907 return true;
7987 }
7988
7989 9788 return false;
7990 15695 }
7991
7992 17546 bool isTouchyType(int32_t type)
7993 {
7994
2/2
✓ Branch 0 taken 6050 times.
✓ Branch 1 taken 11496 times.
17546 switch(type)
7995 {
7996 case cSLASHTOUCHY:
7997 case cSLASHITEMTOUCHY:
7998 case cBUSHTOUCHY:
7999 case cFLOWERSTOUCHY:
8000 case cTALLGRASSTOUCHY:
8001 case cSLASHNEXTTOUCHY:
8002 case cSLASHNEXTITEMTOUCHY:
8003 case cBUSHNEXTTOUCHY:
8004 11496 return true;
8005 }
8006
8007 6050 return false;
8008 17546 }
8009
8010 29332374 bool isCuttableType(int32_t type)
8011 {
8012
2/2
✓ Branch 0 taken 28883109 times.
✓ Branch 1 taken 449265 times.
29332374 switch(type)
8013 {
8014 case cSLASH:
8015 case cSLASHITEM:
8016 case cBUSH:
8017 case cFLOWERS:
8018 case cTALLGRASS:
8019 case cTALLGRASSNEXT:
8020 case cSLASHNEXT:
8021 case cSLASHNEXTITEM:
8022 case cBUSHNEXT:
8023
8024 case cSLASHTOUCHY:
8025 case cSLASHITEMTOUCHY:
8026 case cBUSHTOUCHY:
8027 case cFLOWERSTOUCHY:
8028 case cTALLGRASSTOUCHY:
8029 case cSLASHNEXTTOUCHY:
8030 case cSLASHNEXTITEMTOUCHY:
8031 case cBUSHNEXTTOUCHY:
8032 449265 return true;
8033 }
8034
8035 28883109 return false;
8036 29332374 }
8037
8038 17322 bool isCuttableItemType(int32_t type)
8039 {
8040
2/2
✓ Branch 0 taken 424 times.
✓ Branch 1 taken 16898 times.
17322 switch(type)
8041 {
8042 case cSLASHITEM:
8043 case cBUSH:
8044 case cFLOWERS:
8045 case cTALLGRASS:
8046 case cTALLGRASSNEXT:
8047 case cSLASHNEXTITEM:
8048 case cBUSHNEXT:
8049
8050 case cSLASHITEMTOUCHY:
8051 case cBUSHTOUCHY:
8052 case cFLOWERSTOUCHY:
8053 case cTALLGRASSTOUCHY:
8054 case cSLASHNEXTITEMTOUCHY:
8055 case cBUSHNEXTTOUCHY:
8056 16898 return true;
8057 }
8058
8059 424 return false;
8060 17322 }
8061
8062 66 bool is_push(mapscr* m, int32_t pos)
8063 {
8064
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if(is_push_flag(m->sflag[pos]))
8065 return true;
8066 66 newcombo const& cmb = combobuf[m->data[pos]];
8067
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if(is_push_flag(cmb.flag))
8068 return true;
8069
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 52 times.
66 if(cmb.type == cPUSHBLOCK)
8070 14 return true;
8071
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
52 if(cmb.type == cSWITCHHOOK && (cmb.usrflags&cflag7))
8072 return true; //Counts as 'pushblock' flag
8073 52 return false;
8074 66 }
8075
8076 412 static std::map<int, screen_state_t> screen_states;
8077
8078 35854 std::map<int, screen_state_t>& get_screen_states()
8079 {
8080 35854 return screen_states;
8081 }
8082
8083 44182923 screen_state_t& get_screen_state(int screen)
8084 {
8085 44182923 return screen_states[screen];
8086 }
8087
8088 575 void clear_screen_states()
8089 {
8090 575 screen_states.clear();
8091 575 }
8092
8093 1439 void screen_item_set_state(int screen, ScreenItemState state)
8094 {
8095 1439 get_screen_state(screen).item_state = state;
8096 1439 }
8097
8098 37019 void mark_visited(int screen)
8099 {
8100
2/2
✓ Branch 0 taken 475 times.
✓ Branch 1 taken 36544 times.
37019 if (screen < 0x80)
8101 {
8102
2/2
✓ Branch 0 taken 24611 times.
✓ Branch 1 taken 11933 times.
36544 if(DMaps[cur_dmap].flags&dmfVIEWMAP)
8103 11933 game->maps[mapind(cur_map, screen)] |= mVISITED;
8104
8105 36544 markBmap(-1, screen);
8106 36544 }
8107 37019 }
8108